History

20091204

forsyth committed 16 years ago

Commit cf8bba71 parent a77a84337 files · +1294 −77Browse files

Unified · Split

37 files
  1. CHANGES +6 −0
  2. appl/charon/build.b +1 −1
  3. appl/charon/chutils.b +4 −9
  4. appl/charon/chutils.m +0 −1
  5. appl/charon/date.b +1 −1
  6. appl/charon/gui.b +3 −3
  7. appl/charon/img.b +3 −3
  8. appl/charon/jscript.b +1 −1
  9. appl/charon/layout.b +7 −7
  10. appl/cmd/mount.b +3 −5
  11. appl/lib/styxconv/mkfile +4 −2
  12. appl/lib/styxconv/new2old.b +640 −0
  13. appl/lib/styxconv/nsys.m +51 −0
  14. appl/lib/styxconv/old2new.b +480 −0
  15. appl/lib/styxconv/ostyx.b +62 −25
  16. appl/lib/styxconv/ostyx.m +3 −1
  17. dis/charon.dis +0 −0
  18. dis/charon/build.dis +0 −0
  19. dis/charon/chutils.dis +0 −0
  20. dis/charon/date.dis +0 −0
  21. dis/charon/file.dis +0 −0
  22. dis/charon/ftp.dis +0 −0
  23. dis/charon/gui.dis +0 −0
  24. dis/charon/http.dis +0 −0
  25. dis/charon/img.dis +0 −0
  26. dis/charon/jscript.dis +0 −0
  27. dis/charon/layout.dis +0 −0
  28. dis/charon/lex.dis +0 −0
  29. dis/lib/styxconv/new2old.dis +0 −0
  30. dis/lib/styxconv/old2new.dis +0 −0
  31. dis/lib/styxconv/ostyx.dis +0 −0
  32. dis/mount.dis +0 −0
  33. include/version.h +1 −1
  34. man/2/styxconv +28 −28
  35. module/styxconv.m +4 −3
  36. os/pc/fns.h +2 −2
  37. os/pc/mmu.c +6 −0
CHANGES+6−0
@@ -1,3 +1,9 @@
120091127
2 problems fixed in styxconv(2), which can now convert both ways [rog]
320091119
4 emu/port/devfs-posix.c missing waserror in dirread (obscure but possible failure)
520091007
6 remove intermediate exception-raising function from charon implementation
120091004720091004
2 restore "keyring" to lib section of emu/Plan9/emu8 restore "keyring" to lib section of emu/Plan9/emu
320090930920090930
appl/charon/build.b+1−1
@@ -1620,7 +1620,7 @@ lexstring(s: string) : array of ref Token · 1619 unmodified lines
1620lastps(psl: list of ref Pstate) : ref Pstate1620lastps(psl: list of ref Pstate) : ref Pstate
1621{1621{
1622 if(psl == nil)1622 if(psl == nil)
1623 CU->raisex("EXInternal: empty pstate stack");1623 raise "EXInternal: empty pstate stack";
1624 while(tl psl != nil)1624 while(tl psl != nil)
1625 psl = tl psl;1625 psl = tl psl;
1626 return hd psl;1626 return hd psl;
appl/charon/chutils.b+4−9
@@ -1227,14 +1227,14 @@ ResourceState.cur() : ResourceState · 1226 unmodified lines
1227 if(mfd == nil)1227 if(mfd == nil)
1228 mfd = sys->open("/dev/memory", sys->OREAD);1228 mfd = sys->open("/dev/memory", sys->OREAD);
1229 if (mfd == nil)1229 if (mfd == nil)
1230 raisex(sys->sprint("can't open /dev/memory: %r"));1230 raise sys->sprint("can't open /dev/memory: %r");
1231 1231
1232 sys->seek(mfd, big 0, Sys->SEEKSTART);1232 sys->seek(mfd, big 0, Sys->SEEKSTART);
1233 1233
1234 buf := array[400] of byte;1234 buf := array[400] of byte;
1235 n := sys->read(mfd, buf, len buf);1235 n := sys->read(mfd, buf, len buf);
1236 if (n <= 0)1236 if (n <= 0)
1237 raisex(sys->sprint("can't read /dev/memory: %r"));1237 raise sys->sprint("can't read /dev/memory: %r");
1238 1238
1239 (nil, l) := sys->tokenize(string buf[0:n], "\n");1239 (nil, l) := sys->tokenize(string buf[0:n], "\n");
1240 # p->cursize, p->maxsize, p->hw, p->nalloc, p->nfree, p->nbrk, poolmax(p), p->name)1240 # p->cursize, p->maxsize, p->hw, p->nalloc, p->nfree, p->nbrk, poolmax(p), p->name)
@@ -1763,7 +1763,7 @@ makestrinttab(a: array of string) : array of T->StringInt · 522 unmodified lines
1763 ans[i].key = a[i];1763 ans[i].key = a[i];
1764 ans[i].val = i;1764 ans[i].val = i;
1765 if(i > 0 && a[i] < a[i-1])1765 if(i > 0 && a[i] < a[i-1])
1766 raisex("EXInternal: table out of alphabetical order");1766 raise "EXInternal: table out of alphabetical order";
1767 }1767 }
1768 return ans;1768 return ans;
1769}1769}
@@ -1866,15 +1866,10 @@ min(a,b: int) : int · 96 unmodified lines
1866 return b;1866 return b;
1867}1867}
1868 1868
1869raisex(e: string)
1870{
1871 raise e;
1872}
1873
1874assert(i: int)1869assert(i: int)
1875{1870{
1876 if(!i) {1871 if(!i) {
1877 raisex("EXInternal: assertion failed");1872 raise "EXInternal: assertion failed";
1878# sys->print("assertion failed\n");1873# sys->print("assertion failed\n");
1879# s := hmeth[-1];1874# s := hmeth[-1];
1880 }1875 }
appl/charon/chutils.m+0−1
@@ -360,7 +360,6 @@ CharonUtils: module · 359 unmodified lines
360 color: fn(s: string, dflt: int) : int;360 color: fn(s: string, dflt: int) : int;
361 max: fn(a, b : int) : int;361 max: fn(a, b : int) : int;
362 min: fn(a, b : int) : int;362 min: fn(a, b : int) : int;
363 raisex: fn(e: string);
364 assert: fn(i: int);363 assert: fn(i: int);
365 stripscript: fn(s: string) : string; # strip HTML comments from Script364 stripscript: fn(s: string) : string; # strip HTML comments from Script
366 getconv: fn(chset : string) : Btos;365 getconv: fn(chset : string) : Btos;
appl/charon/date.b+1−1
@@ -23,7 +23,7 @@ init(cu: CharonUtils) · 22 unmodified lines
23 CU = cu;23 CU = cu;
24 daytime = load Daytime Daytime->PATH;24 daytime = load Daytime Daytime->PATH;
25 if (daytime==nil)25 if (daytime==nil)
26 CU->raisex(sys->sprint("EXInternal: can't load Daytime: %r"));26 raise sys->sprint("EXInternal: can't load Daytime: %r");
27}27}
28 28
29# print dates in the format29# print dates in the format
appl/charon/gui.b+3−3
@@ -98,7 +98,7 @@ init(ctxt: ref Draw->Context, cu: CharonUtils): ref Draw->Context · 97 unmodified lines
98 tk = load Tk Tk->PATH;98 tk = load Tk Tk->PATH;
99 tkclient = load Tkclient Tkclient->PATH;99 tkclient = load Tkclient Tkclient->PATH;
100 if(tkclient == nil)100 if(tkclient == nil)
101 CU->raisex(sys->sprint("EXInternal: can't load module Tkclient: %r"));101 raise sys->sprint("EXInternal: can't load module Tkclient: %r");
102 tkclient->init();102 tkclient->init();
103 103
104 wmctl: chan of string;104 wmctl: chan of string;
@@ -386,11 +386,11 @@ makewins() · 281 unmodified lines
386 realwin = screen.newwindow(r, D->Refnone, D->White);386 realwin = screen.newwindow(r, D->Refnone, D->White);
387 realwin.origin(ZP, r.min);387 realwin.origin(ZP, r.min);
388 if(realwin == nil)388 if(realwin == nil)
389 CU->raisex(sys->sprint("EXFatal: can't initialize windows: %r"));389 raise sys->sprint("EXFatal: can't initialize windows: %r");
390 390
391 mainwin = display.newimage(realwin.r, realwin.chans, 0, D->White);391 mainwin = display.newimage(realwin.r, realwin.chans, 0, D->White);
392 if(mainwin == nil)392 if(mainwin == nil)
393 CU->raisex(sys->sprint("EXFatal: can't initialize windows: %r"));393 raise sys->sprint("EXFatal: can't initialize windows: %r");
394}394}
395 395
396hidewins()396hidewins()
appl/charon/img.b+3−3
@@ -161,7 +161,7 @@ imgerror(is: ref ImageSource, msg: string) · 160 unmodified lines
161 is.err = msg;161 is.err = msg;
162 if(dbg)162 if(dbg)
163 sys->print("Image error: %s\n", msg);163 sys->print("Image error: %s\n", msg);
164 CU->raisex("exImageerror:");164 raise "exImageerror:";
165}165}
166 166
167# Get next char or raise exception if cannot167# Get next char or raise exception if cannot
@@ -179,7 +179,7 @@ getc(is: ref ImageSource) : int · 11 unmodified lines
179ungetc(is: ref ImageSource)179ungetc(is: ref ImageSource)
180{180{
181 if(is.i == 0)181 if(is.i == 0)
182 CU->raisex("EXInternal: ungetc past beginning of buffer");182 raise "EXInternal: ungetc past beginning of buffer";
183 is.i--;183 is.i--;
184}184}
185 185
@@ -190,7 +190,7 @@ ungetc2(is: ref ImageSource, nil: byte) · 4 unmodified lines
190{190{
191 if(is.i < 2) {191 if(is.i < 2) {
192 if(is.i != 1)192 if(is.i != 1)
193 CU->raisex("EXInternal: ungetc2 past beginning of buffer");193 raise "EXInternal: ungetc2 past beginning of buffer";
194 is.i = 0;194 is.i = 0;
195 }195 }
196 else196 else
appl/charon/jscript.b+1−1
@@ -2107,7 +2107,7 @@ specindex(class: string) : int · 2106 unmodified lines
2107 if(objspecs[i].name == class)2107 if(objspecs[i].name == class)
2108 break;2108 break;
2109 if(i == len objspecs)2109 if(i == len objspecs)
2110 CU->raisex("EXInternal: couldn't find host object class " + class);2110 raise "EXInternal: couldn't find host object class " + class;
2111 return i;2111 return i;
2112}2112}
2113 2113
appl/charon/layout.b+7−7
@@ -516,7 +516,7 @@ createvscroll(f: ref Frame) · 515 unmodified lines
516 f.vscr.r = f.vscr.r.addpt(Point(f.cr.max.x-breadth, f.cr.min.y));516 f.vscr.r = f.vscr.r.addpt(Point(f.cr.max.x-breadth, f.cr.min.y));
517 f.cr.max.x -= breadth;517 f.cr.max.x -= breadth;
518 if(f.cr.dx() <= 2*f.marginw)518 if(f.cr.dx() <= 2*f.marginw)
519 CU->raisex("EXInternal: frame too small for layout");519 raise "EXInternal: frame too small for layout";
520 f.vscr.draw(1);520 f.vscr.draw(1);
521}521}
522 522
@@ -531,7 +531,7 @@ createhscroll(f: ref Frame) · 8 unmodified lines
531 f.hscr.r = f.hscr.r.addpt(Point(x,f.cr.max.y-breadth));531 f.hscr.r = f.hscr.r.addpt(Point(x,f.cr.max.y-breadth));
532 f.cr.max.y -= breadth;532 f.cr.max.y -= breadth;
533 if(f.cr.dy() <= 2*f.marginh)533 if(f.cr.dy() <= 2*f.marginh)
534 CU->raisex("EXInternal: frame too small for layout");534 raise "EXInternal: frame too small for layout";
535 f.hscr.draw(1);535 f.hscr.draw(1);
536}536}
537 537
@@ -985,7 +985,7 @@ fixlinegeom(f: ref Frame, lay: ref Lay, l: ref Line) · 447 unmodified lines
985 # line is complete, next line will start with it (or it is nil)985 # line is complete, next line will start with it (or it is nil)
986 rest := it;986 rest := it;
987 if(lastit == nil)987 if(lastit == nil)
988 CU->raisex("EXInternal: no items on line");988 raise "EXInternal: no items on line";
989 lastit.next = nil;989 lastit.next = nil;
990 990
991 l.width = w;991 l.width = w;
@@ -1087,7 +1087,7 @@ getfont(num: int) : ref Font · 95 unmodified lines
1087 f = Font.open(display, fonts[num].name);1087 f = Font.open(display, fonts[num].name);
1088 if(f == nil) {1088 if(f == nil) {
1089 if(num == DefFnt)1089 if(num == DefFnt)
1090 CU->raisex(sys->sprint("exLayout: can't open default font %s: %r", fonts[num].name));1090 raise sys->sprint("exLayout: can't open default font %s: %r", fonts[num].name);
1091 else {1091 else {
1092 if(int (CU->config).dbg['w'])1092 if(int (CU->config).dbg['w'])
1093 sys->print("warning: substituting default for font %s\n",1093 sys->print("warning: substituting default for font %s\n",
@@ -2389,7 +2389,7 @@ markchanges(loc: ref Loc) · 1295 unmodified lines
2389 }2389 }
2390 LEtablecell =>2390 LEtablecell =>
2391 if(lastf == nil)2391 if(lastf == nil)
2392 CU->raisex("EXInternal: markchanges no lastf");2392 raise "EXInternal: markchanges no lastf";
2393 c := loc.le[i].tcell;2393 c := loc.le[i].tcell;
2394 clay := lastf.sublays[c.layid];2394 clay := lastf.sublays[c.layid];
2395 if(clay != nil)2395 if(clay != nil)
@@ -2424,7 +2424,7 @@ colorimage(rgb: int) : ref Image · 28 unmodified lines
2424# im := display.color(pix);2424# im := display.color(pix);
2425 im := display.rgb((rgb>>16)&255, (rgb>>8)&255, rgb&255);2425 im := display.rgb((rgb>>16)&255, (rgb>>8)&255, rgb&255);
2426 if(im == nil)2426 if(im == nil)
2427 CU->raisex(sys->sprint("exLayout: can't allocate color #%8.8ux: %r", rgb));2427 raise sys->sprint("exLayout: can't allocate color #%8.8ux: %r", rgb);
2428 x = ref Colornode(rgb, im, xhd);2428 x = ref Colornode(rgb, im, xhd);
2429 colorhashtab[hv] = x;2429 colorhashtab[hv] = x;
2430 }2430 }
@@ -3309,7 +3309,7 @@ Control.scrollset(c: self ref Control, v1, v2, vmax, nsteps, draw: int) · 878 unmodified lines
3309 if(l <= 0)3309 if(l <= 0)
3310 l = 1;3310 l = 1;
3311 if(l < 0)3311 if(l < 0)
3312 CU->raisex("EXInternal: negative scrollbar trough");3312 raise "EXInternal: negative scrollbar trough";
3313 sc.top = l*v1/vmax;3313 sc.top = l*v1/vmax;
3314 sc.bot = l*(vmax-v2)/vmax;3314 sc.bot = l*(vmax-v2)/vmax;
3315 if (nsteps == 0)3315 if (nsteps == 0)
appl/cmd/mount.b+3−5
@@ -215,17 +215,15 @@ runcmd(sh: Sh, ctxt: ref Draw->Context, argv: list of string, stdin: ref Sys->FD · 214 unmodified lines
215 215
216cvstyx(fd: ref Sys->FD): (ref Sys->FD, string)216cvstyx(fd: ref Sys->FD): (ref Sys->FD, string)
217{217{
218 styxconv := load Styxconv Styxconv->PATH;218 styxconv := load Styxconv Styxconv->PATHNEW2OLD;
219 if(styxconv == nil)219 if(styxconv == nil)
220 return (nil, sys->sprint("cannot load %s: %r", Styxconv->PATH));220 return (nil, sys->sprint("cannot load %s: %r", Styxconv->PATHNEW2OLD));
221 styxconv->init();221 styxconv->init();
222 p := array[2] of ref Sys->FD;222 p := array[2] of ref Sys->FD;
223 if(sys->pipe(p) < 0)223 if(sys->pipe(p) < 0)
224 return (nil, sys->sprint("can't create pipe: %r"));224 return (nil, sys->sprint("can't create pipe: %r"));
225 pidc := chan of int;225 spawn styxconv->styxconv(p[1], fd);
226 spawn styxconv->styxconv(p[1], fd, pidc);
227 p[1] = nil;226 p[1] = nil;
228 <-pidc;
229 return (p[0], nil);227 return (p[0], nil);
230}228}
231 229
appl/lib/styxconv/mkfile+4−2
@@ -2,11 +2,13 @@ · 1 unmodified line
2 2
3TARG=\3TARG=\
4 ostyx.dis\4 ostyx.dis\
5 styxconv.dis\5 new2old.dis\
6 6 old2new.dis\
7
7MODULES=\8MODULES=\
8 ostyx.m\9 ostyx.m\
9 osys.m\10 osys.m\
11 nsys.m\
10 12
11SYSMODULES=\13SYSMODULES=\
12 bufio.m\14 bufio.m\
appl/lib/styxconv/new2old.b+640−0
@@ -0,0 +1,640 @@
1implement Styxconv;
2
3include "sys.m";
4 sys: Sys;
5include "osys.m";
6include "nsys.m";
7include "draw.m";
8include "styx.m";
9 nstyx: Styx;
10 Tmsg, Rmsg: import nstyx;
11include "ostyx.m";
12 ostyx: OStyx;
13 OTmsg, ORmsg: import ostyx;
14include "styxconv.m";
15
16# todo: map fids > ffff into 16 bits
17
18DEBUG: con 1;
19
20Fid: adt
21{
22 fid: int;
23 isdir: int;
24 n: int; # size of last new client dirread request.
25 soff: int; # dir offset on old server.
26 coff: int; # dir offset on new client.
27 next: cyclic ref Fid;
28};
29
30Req: adt {
31 tag: int;
32 oldtag: int; # if it's a flush.
33 rp: ref Reqproc;
34 next: cyclic ref Req;
35 flushes: list of ref Rmsg.Flush; # flushes awaiting req finish.
36};
37
38Reqproc: adt {
39 newtmsg: chan of ref Tmsg; # convproc -> reqproc, once per req.
40 newrmsg: chan of ref Rmsg; # reqproc -> convproc, once per req
41
42 oldtmsg: chan of ref OTmsg; # reqproc -> convproc
43 oldrmsg: chan of ref ORmsg; # convproc -> reqproc
44
45 flushable: int;
46
47 new: fn(): ref Reqproc;
48 rpc: fn(rp: self ref Reqproc, otm: ref OTmsg): ref ORmsg;
49};
50
51tags: ref Req;
52avail: chan of ref Reqproc;
53fids: ref Fid;
54nprocs := 0;
55
56init()
57{
58 sys = load Sys Sys->PATH;
59 if(sys == nil)
60 nomod("Sys", Sys->PATH);
61 nstyx = load Styx Styx->PATH;
62 if(nstyx == nil)
63 nomod("Styx", Styx->PATH);
64 ostyx = load OStyx OStyx->PATH;
65 if(ostyx == nil)
66 nomod("OStyx", OStyx->PATH);
67
68 ostyx->init();
69 nstyx->init();
70 avail = chan of ref Reqproc;
71}
72
73styxconv(newclient: ref Sys->FD, oldsrv: ref Sys->FD)
74{
75 newtmsg := chan of ref Tmsg;
76 oldrmsg := chan of ref ORmsg;
77
78 killpids := chan[2] of int;
79 spawn readnewtmsgs(killpids, newclient, newtmsg);
80 spawn readoldrmsgs(killpids, oldsrv, oldrmsg);
81
82converting:
83 for(;;)alt{
84 ntm := <-newtmsg =>
85 if(DEBUG)
86 sys->fprint(sys->fildes(2), "-> %s\n", ntm.text());
87 if(ntm == nil)
88 break converting;
89 ns2os(ntm, newclient, oldsrv);
90 orm := <-oldrmsg =>
91 if(DEBUG)
92 sys->fprint(sys->fildes(2), " <- %s\n", ostyx->rmsg2s(orm));
93 if(orm == nil)
94 break converting;
95 t := looktag(orm.tag);
96 if(t == nil){
97 warning("reply by old-server to non-existent tag");
98 break;
99 }
100 pick rm := orm {
101 Flush =>
102 ot := looktag(t.oldtag);
103 # if it's an Rflush of a request-in-progress,
104 # we send it to the reqproc, which
105 # can then clean up as it likes.
106 if(ot != nil){
107 if(ot.rp != nil){
108 if(ot.rp.flushable){
109 ot.rp.oldrmsg <-= rm;
110 # reqproc is bound to finish after a flush
111 reqreply(ot, newclient, oldsrv);
112 }else {
113 # hold flush reply for later
114 ot.flushes = ref Rmsg.Flush(rm.tag) :: ot.flushes;
115 }
116 break;
117 }
118 deletetag(t.oldtag);
119 }
120 NRsend(newclient, ref Rmsg.Flush(rm.tag));
121 deletetag(rm.tag);
122 * =>
123 if(t.rp != nil){
124 t.rp.oldrmsg <-= orm;
125 reqreply(t, newclient, oldsrv);
126 }else{
127 os2ns(orm, newclient);
128 deletetag(orm.tag);
129 }
130 }
131 }
132 # kill off active reqprocs
133 for(; tags != nil; tags = tags.next){
134 if(tags.rp != nil){
135 tags.rp.oldrmsg <-= nil;
136 nprocs--;
137 }
138 }
139 # kill off idle reqprocs
140 while(nprocs > 0){
141 rp := <-avail;
142 rp.newtmsg <-= nil;
143 nprocs--;
144 }
145 # kill off message readers
146 kill(<-killpids);
147 kill(<-killpids);
148}
149
150# process one response from the request proc.
151# request proc can respond by sending a new tmsg to the old server
152# or by sending an rmsg to the new client, in which case
153# it implicitly signals that it has finished processing the request.
154# the actual reply might be an Rflush, signifying that
155# the request has been aborted.
156reqreply(t: ref Req, newclient: ref Sys->FD, oldsrv: ref Sys->FD)
157{
158 rp := t.rp;
159 alt{
160 nrm := <-rp.newrmsg =>
161 # request is done when process sends rmsg
162 pick rm := nrm {
163 Flush =>
164 deletetag(t.tag);
165 }
166 deletetag(nrm.tag);
167 NRsend(newclient, nrm);
168 for(; t.flushes != nil; t.flushes = tl t.flushes)
169 NRsend(newclient, hd t.flushes);
170
171 otm := <-rp.oldtmsg =>
172 OTsend(oldsrv, otm);
173 }
174}
175
176
177# T messages: forward on, reply immediately, or start processing.
178ns2os(tm0: ref Tmsg, newclient, oldsrv: ref Sys->FD)
179{
180 otm: ref OTmsg;
181
182 t := ref Req(tm0.tag, -1, nil, nil, nil);
183 pick tm := tm0{
184 Readerror =>
185 exit;
186 Version =>
187 (s, v) := nstyx->compatible(tm, nstyx->MAXRPC, nil);
188 NRsend(newclient, ref Rmsg.Version(tm.tag, s, v));
189 return;
190 Auth =>
191 NRsend(newclient, ref Rmsg.Error(tm.tag, "authorization not required"));
192 return;
193 Walk =>
194 storetag(t);
195 t.rp = Reqproc.new();
196 t.rp.newtmsg <-= tm;
197 reqreply(t, newclient, oldsrv);
198 return;
199 Attach =>
200 otm = ref OTmsg.Attach(tm.tag, tm.fid, tm.uname, tm.aname);
201 Flush =>
202 t.oldtag = tm.oldtag;
203 otm = ref OTmsg.Flush(tm.tag, tm.oldtag);
204 Open =>
205 otm = ref OTmsg.Open(tm.tag, tm.fid, tm.mode);
206 Create =>
207 otm = ref OTmsg.Create(tm.tag, tm.fid, tm.perm, tm.mode, tm.name);
208 Read =>
209 fp := findfid(tm.fid);
210 count := tm.count;
211 offset := tm.offset;
212 if(fp != nil && fp.isdir){
213 fp.n = count;
214 count = (count/OStyx->DIRLEN)*OStyx->DIRLEN;
215 if(int offset != fp.coff){
216 NRsend(newclient, ref Rmsg.Error(tm.tag, "unexpected offset in dirread"));
217 return;
218 }
219 offset = big fp.soff;
220 }
221 otm = ref OTmsg.Read(tm.tag, tm.fid, count, offset);
222 Write =>
223 otm = ref OTmsg.Write(tm.tag, tm.fid, tm.offset, tm.data);
224 Clunk =>
225 otm = ref OTmsg.Clunk(tm.tag, tm.fid);
226 Remove =>
227 otm = ref OTmsg.Remove(tm.tag, tm.fid);
228 Stat =>
229 otm = ref OTmsg.Stat(tm.tag, tm.fid);
230 Wstat =>
231 otm = ref OTmsg.Wstat(tm.tag, tm.fid, nd2od(tm.stat));
232 * =>
233 fatal("bad T message");
234 }
235 storetag(t);
236 OTsend(oldsrv, otm);
237}
238
239# R messages: old to new
240os2ns(orm0: ref ORmsg, newclient: ref Sys->FD)
241{
242 rm: ref Rmsg;
243
244 rm = nil;
245 pick orm := orm0 {
246 Error =>
247 rm = ref Rmsg.Error(orm.tag, orm.err);
248 Flush =>
249 rm = ref Rmsg.Flush(orm.tag);
250 Clone =>
251 rm = ref Rmsg.Walk(orm.tag, nil);
252 Walk =>
253 fatal("walk rmsgs should be dealt with be walkreqproc");
254 Open =>
255 setfid(orm.fid, orm.qid);
256 rm = ref Rmsg.Open(orm.tag, oq2nq(orm.qid), 0);
257 Create =>
258 setfid(orm.fid, orm.qid);
259 rm = ref Rmsg.Create(orm.tag, oq2nq(orm.qid), 0);
260 Read =>
261 fp := findfid(orm.fid);
262 data := orm.data;
263 if(fp != nil && fp.isdir)
264 data = ods2nds(data, fp.n);
265 fp.coff += len data;
266 fp.soff += len orm.data;
267 rm = ref Rmsg.Read(orm.tag, data);
268 Write =>
269 rm = ref Rmsg.Write(orm.tag, orm.count);
270 Clunk =>
271 rm = ref Rmsg.Clunk(orm.tag);
272 deletefid(orm.fid);
273 Remove =>
274 rm = ref Rmsg.Remove(orm.tag);
275 deletefid(orm.fid);
276 Stat =>
277 rm = ref Rmsg.Stat(orm.tag, od2nd(orm.stat));
278 Wstat =>
279 rm = ref Rmsg.Wstat(orm.tag);
280 Attach =>
281 newfid(orm.fid, orm.qid.path & OSys->CHDIR);
282 rm = ref Rmsg.Attach(orm.tag, oq2nq(orm.qid));
283 * =>
284 fatal("bad R message");
285 }
286 NRsend(newclient, rm);
287}
288
289Reqproc.rpc(rp: self ref Reqproc, otm: ref OTmsg): ref ORmsg
290{
291 rp.oldtmsg <-= otm;
292 m := <-rp.oldrmsg;
293 if(m == nil)
294 exit;
295 return m;
296}
297
298Reqproc.new(): ref Reqproc
299{
300 alt{
301 rp := <-avail =>
302 return rp;
303 * =>
304 rp := ref Reqproc(
305 chan of ref Tmsg,
306 chan of ref Rmsg,
307 chan of ref OTmsg,
308 chan of ref ORmsg,
309 1);
310 spawn reqproc(rp);
311 nprocs++;
312 return rp;
313 }
314}
315
316reqproc(rp: ref Reqproc)
317{
318 for(;;){
319 tm := <-rp.newtmsg;
320 if(tm == nil)
321 return;
322 rm: ref Rmsg;
323 pick m := tm {
324 Walk =>
325 rm = walkreq(m, rp);
326 * =>
327 fatal("non-walk req passed to reqproc");
328 }
329 rp.flushable = 1;
330 rp.newrmsg <-= rm;
331 avail <-= rp;
332 }
333}
334
335# note that although this is in a separate process,
336# whenever it's not in Reqproc.rpc, the styxconv
337# process is blocked, so although state is shared,
338# there are no race conditions.
339walkreq(tm: ref Tmsg.Walk, rp: ref Reqproc): ref Rmsg
340{
341 cloned := 0;
342 n := len tm.names;
343 if(tm.newfid != tm.fid){
344 cloned = 1;
345 pick rm := rp.rpc(ref OTmsg.Clone(tm.tag, tm.fid, tm.newfid)) {
346 Clone =>
347 ;
348 Error =>
349 return ref Rmsg.Error(tm.tag, rm.err);
350 Flush =>
351 return ref Rmsg.Flush(rm.tag);
352 * =>
353 fatal("unexpected reply to OTmsg.Clone");
354 }
355 cloned = 1;
356 }
357 qids := array[n] of NSys->Qid;
358 finalqid: OSys->Qid;
359
360 # make sure we don't get flushed in an unwindable state.
361 rp.flushable = n == 1 || cloned;
362 for(i := 0; i < n; i++){
363 pick rm := rp.rpc(ref OTmsg.Walk(tm.tag, tm.newfid, tm.names[i])) {
364 Walk =>
365 qids[i] = oq2nq(rm.qid);
366 finalqid = rm.qid;
367 Flush =>
368 if(cloned){
369 rp.flushable = 0;
370 rp.rpc(ref OTmsg.Clunk(tm.tag, tm.newfid));
371 }
372 return ref Rmsg.Flush(rm.tag);
373 Error =>
374 if(cloned){
375 rp.flushable = 0;
376 rp.rpc(ref OTmsg.Clunk(tm.tag, tm.newfid));
377 }
378 if(i == 0)
379 return ref Rmsg.Error(tm.tag, rm.err);
380 return ref Rmsg.Walk(tm.tag, qids[0:i]);
381 }
382 }
383 if(cloned)
384 clonefid(tm.fid, tm.newfid);
385 if(n > 0)
386 setfid(tm.newfid, finalqid);
387 return ref Rmsg.Walk(tm.tag, qids);
388}
389
390storetag(t: ref Req)
391{
392 t.next = tags;
393 tags = t;
394}
395
396looktag(tag: int): ref Req
397{
398 for(t := tags; t != nil; t = t.next)
399 if(t.tag == tag)
400 return t;
401 return nil;
402}
403
404deletetag(tag: int)
405{
406 prev: ref Req;
407 t := tags;
408 while(t != nil){
409 if(t.tag == tag){
410 next := t.next;
411 t.next = nil;
412 if(prev != nil)
413 prev.next = next;
414 else
415 tags = next;
416 t = next;
417 }else{
418 prev = t;
419 t = t.next;
420 }
421 }
422}
423
424newfid(fid: int, isdir: int): ref Fid
425{
426 f := ref Fid;
427 f.fid = fid;
428 f.isdir = isdir;
429 f.n = f.soff = f.coff = 0;
430 f.next = fids;
431 fids = f;
432 return f;
433}
434
435clonefid(ofid: int, fid: int): ref Fid
436{
437 if((f := findfid(ofid)) != nil){
438 nf := newfid(fid, f.isdir);
439 return nf;
440 }
441 warning("clone of non-existent fid");
442 return newfid(fid, 0);
443}
444
445deletefid(fid: int)
446{
447 lf: ref Fid;
448
449 for(f := fids; f != nil; f = f.next){
450 if(f.fid == fid){
451 if(lf == nil)
452 fids = f.next;
453 else
454 lf.next = f.next;
455 return;
456 }
457 lf = f;
458 }
459}
460
461findfid(fid: int): ref Fid
462{
463 for(f := fids; f != nil; f = f.next)
464 if(f.fid == fid)
465 return f;
466 return nil;
467}
468
469setfid(fid: int, qid: OSys->Qid)
470{
471 f := findfid(fid);
472 if(f == nil){
473 warning(sys->sprint("cannot find fid %d", fid));
474 }else{
475 f.isdir = qid.path & OSys->CHDIR;
476 }
477}
478
479om2nm(om: int): int
480{
481 # DMDIR == CHDIR
482 return om;
483}
484
485nm2om(m: int): int
486{
487 # DMDIR == CHDIR
488 return m&~(NSys->DMAPPEND|NSys->DMEXCL|NSys->DMAUTH);
489}
490
491oq2nq(oq: OSys->Qid): NSys->Qid
492{
493 q: NSys->Qid;
494
495 isdir := oq.path&OSys->CHDIR;
496 q.path = big (oq.path&~OSys->CHDIR);
497 q.vers = oq.vers;
498 q.qtype = 0;
499 if(isdir)
500 q.qtype |= NSys->QTDIR;
501 return q;
502}
503
504nq2oq(q: NSys->Qid): OSys->Qid
505{
506 oq: OSys->Qid;
507
508 isdir := q.qtype&NSys->QTDIR;
509 oq.path = int q.path;
510 oq.vers = q.vers;
511 if(isdir)
512 oq.path |= OSys->CHDIR;
513 return oq;
514}
515
516od2nd(od: OSys->Dir): NSys->Dir
517{
518 d: NSys->Dir;
519
520 d.name = od.name;
521 d.uid = od.uid;
522 d.gid = od.gid;
523 d.muid = od.uid;
524 d.qid = oq2nq(od.qid);
525 d.mode = om2nm(od.mode);
526 d.atime = od.atime;
527 d.mtime = od.mtime;
528 d.length = big od.length;
529 d.dtype = od.dtype;
530 d.dev = od.dev;
531 return d;
532}
533
534nd2od(d: NSys->Dir): OSys->Dir
535{
536 od: OSys->Dir;
537
538 od.name = d.name;
539 od.uid = d.uid;
540 od.gid = d.gid;
541 od.qid = nq2oq(d.qid);
542 od.mode = nm2om(d.mode);
543 od.atime = d.atime;
544 od.mtime = d.mtime;
545 od.length = int d.length;
546 od.dtype = d.dtype;
547 od.dev = d.dev;
548 return od;
549}
550
551ods2nds(ob: array of byte, max: int): array of byte
552{
553 od: OSys->Dir;
554
555 m := len ob;
556 if(m % OStyx->DIRLEN != 0)
557 fatal(sys->sprint("bad dir len %d", m));
558 m /= OStyx->DIRLEN;
559 n := 0;
560 p := ob;
561 for(i := 0; i < m; i++){
562 (p, od) = ostyx->convM2D(p);
563 d := od2nd(od);
564 nn := nstyx->packdirsize(d);
565 if(n+nn > max) # might just happen with long file names
566 break;
567 n += nn;
568 }
569 m = i;
570 b := array[n] of byte;
571 n = 0;
572 p = ob;
573 for(i = 0; i < m; i++){
574 (p, od) = ostyx->convM2D(p);
575 d := od2nd(od);
576 q := nstyx->packdir(d);
577 nn := len q;
578 b[n: ] = q[0: nn];
579 n += nn;
580 }
581 return b;
582}
583
584OTsend(fd: ref Sys->FD, otm: ref OTmsg): int
585{
586 if(DEBUG)
587 sys->fprint(sys->fildes(2), " -> %s\n", ostyx->tmsg2s(otm));
588 s := array[OStyx->MAXRPC] of byte;
589 n := ostyx->tmsg2d(otm, s);
590 if(n < 0)
591 return -1;
592 return sys->write(fd, s, n);
593}
594
595NRsend(fd: ref Sys->FD, rm: ref Rmsg): int
596{
597 if(DEBUG)
598 sys->fprint(sys->fildes(2), "<- %s\n", rm.text());
599 s := rm.pack();
600 if(s == nil)
601 return -1;
602 return sys->write(fd, s, len s);
603}
604
605readnewtmsgs(pidc: chan of int, newclient: ref Sys->FD, newtmsg: chan of ref Tmsg)
606{
607 pidc <-= sys->pctl(0, nil);
608 for(;;){
609 newtmsg <-= Tmsg.read(newclient, nstyx->MAXRPC);
610 }
611}
612
613readoldrmsgs(pidc: chan of int, oldsrv: ref Sys->FD, oldrmsg: chan of ref ORmsg)
614{
615 pidc <-= sys->pctl(0, nil);
616 for(;;){
617 oldrmsg <-= ORmsg.read(oldsrv);
618 }
619}
620
621warning(err: string)
622{
623 sys->fprint(sys->fildes(2), "warning: %s\n", err);
624}
625
626fatal(err: string)
627{
628 sys->fprint(sys->fildes(2), "%s\n", err);
629 exit;
630}
631
632nomod(mod: string, path: string)
633{
634 fatal(sys->sprint("can't load %s(%s): %r", mod, path));
635}
636
637kill(pid: int)
638{
639 sys->fprint(sys->open("#p/"+string pid+"/ctl", Sys->OWRITE), "kill");
640}
appl/lib/styxconv/nsys.m+51−0
@@ -0,0 +1,51 @@
1NSys: module
2{
3 # Unique file identifier for file objects
4 Qid: adt
5 {
6 path: big;
7 vers: int;
8 qtype: int;
9 };
10
11 QTDIR: con 16r80;
12 QTAPPEND: con 16r40;
13 QTEXCL: con 16r20;
14 QTAUTH: con 16r08;
15 QTTMP: con 16r04;
16 QTFILE: con 0;
17
18 # Return from stat and directory read
19 Dir: adt
20 {
21 name: string;
22 uid: string;
23 gid: string;
24 muid: string;
25 qid: Qid;
26 mode: int;
27 atime: int;
28 mtime: int;
29 length: big;
30 dtype: int;
31 dev: int;
32 };
33
34 # Maximum read which will be completed atomically;
35 # also the optimum block size
36 #
37 ATOMICIO: con 8192;
38
39 OREAD: con 0;
40 OWRITE: con 1;
41 ORDWR: con 2;
42 OTRUNC: con 16;
43 ORCLOSE: con 64;
44 OEXCL: con 16r1000;
45
46 DMDIR: con int 1<<31;
47 DMAPPEND: con int 1<<30;
48 DMEXCL: con int 1<<29;
49 DMAUTH: con int 1<<27;
50 DMTMP: con int 1<<26;
51};
appl/lib/styxconv/old2new.b+480−0
@@ -0,0 +1,480 @@
1implement Styxconv;
2
3include "sys.m";
4 sys: Sys;
5include "osys.m";
6include "nsys.m";
7include "draw.m";
8include "styx.m";
9 nstyx: Styx;
10 Tmsg, Rmsg: import nstyx;
11include "ostyx.m";
12 ostyx: OStyx;
13 OTmsg, ORmsg: import ostyx;
14include "styxconv.m";
15
16DEBUG: con 0;
17
18# convert from old styx client to new styx server.
19# more straightforward than the other way around
20# because there's an almost exactly 1-1 mapping
21# between message types. (the exception is Tversion,
22# but we do that synchronously anyway).
23
24# todo: map qids > ffffffff into 32 bits.
25
26Msize: con nstyx->IOHDRSZ + OSys->ATOMICIO;
27Fid: adt
28{
29 fid: int;
30 isdir: int;
31 n: int; # size of last new client dirread request.
32 soff: int; # dir offset on new server.
33 coff: int; # dir offset on old client.
34 next: cyclic ref Fid;
35 extras: array of byte; # packed old styx dir structures
36};
37
38Req: adt {
39 tag: int;
40 fid: int;
41 oldtag: int; # if it's a flush.
42 newfid: int; # if it's a clone
43 next: cyclic ref Req;
44};
45
46tags: ref Req;
47fids: ref Fid;
48
49init()
50{
51 sys = load Sys Sys->PATH;
52 if(sys == nil)
53 nomod("Sys", Sys->PATH);
54 nstyx = load Styx Styx->PATH;
55 if(nstyx == nil)
56 nomod("Styx", Styx->PATH);
57 ostyx = load OStyx OStyx->PATH;
58 if(ostyx == nil)
59 nomod("OStyx", OStyx->PATH);
60
61 ostyx->init();
62 nstyx->init();
63}
64
65styxconv(oldclient, newsrv: ref Sys->FD)
66{
67 oldtmsg := chan of ref OTmsg;
68 newrmsg := chan of ref Rmsg;
69
70 killpids := chan[2] of int;
71 spawn readoldtmsgs(killpids, oldclient, oldtmsg);
72 spawn readnewrmsgs(killpids, newsrv, newrmsg);
73 # XXX difficulty: what happens if the server isn't responding
74 # and the client hangs up? we won't know about it.
75 # but we don't want to know about normal t-messages
76 # piling up either, so we don't want to alt on oldtmsg too.
77 NTsend(newsrv, ref Tmsg.Version(nstyx->NOTAG, Msize, "9P2000"));
78 pick nrm := <-newrmsg {
79 Version =>
80 if(DEBUG)
81 sys->fprint(sys->fildes(2), " <- %s\n", nrm.text());
82 if(nrm.msize < Msize)
83 fatal("message size too small");
84 Error =>
85 fatal("versioning failed: " + nrm.ename);
86 * =>
87 fatal("bad response to Tversion: " + nrm.text());
88 }
89
90converting:
91 for(;;)alt{
92 otm := <-oldtmsg =>
93 if(DEBUG)
94 sys->fprint(sys->fildes(2), "-> %s\n", ostyx->tmsg2s(otm));
95 if(otm == nil || tagof(otm) == tagof(OTmsg.Readerror))
96 break converting;
97 oc2ns(otm, oldclient, newsrv);
98 nrm := <-newrmsg =>
99 if(DEBUG)
100 sys->fprint(sys->fildes(2), " <- %s\n", nrm.text());
101 if(nrm == nil || tagof(nrm) == tagof(Rmsg.Readerror))
102 break converting;
103 t := looktag(nrm.tag);
104 if(t == nil){
105 warning("reply by new-server to non-existent tag");
106 break;
107 }
108 ns2oc(t, nrm, oldclient);
109 deletetag(nrm.tag);
110 }
111
112 kill(<-killpids);
113 kill(<-killpids);
114}
115
116# T messages: forward on or reply immediately
117oc2ns(tm0: ref OTmsg, oldclient, newsrv: ref Sys->FD)
118{
119 ntm: ref Tmsg;
120
121 t := ref Req(tm0.tag, -1, -1, -1, nil);
122 pick tm := tm0{
123 Nop =>
124 ORsend(oldclient, ref ORmsg.Nop(tm.tag));
125 return;
126 Attach =>
127 t.fid = tm.fid;
128 ntm = ref Tmsg.Attach(tm.tag, tm.fid, nstyx->NOFID, tm.uname, tm.aname);
129 Clone =>
130 t.fid = tm.fid;
131 t.newfid = tm.newfid;
132 ntm = ref Tmsg.Walk(tm.tag, tm.fid, tm.newfid, nil);
133 Walk =>
134 t.fid = tm.fid;
135 ntm = ref Tmsg.Walk(tm.tag, tm.fid, tm.fid, array[] of {tm.name});
136 Flush =>
137 t.oldtag = tm.oldtag;
138 ntm = ref Tmsg.Flush(tm.tag, tm.oldtag);
139 Open =>
140 t.fid = tm.fid;
141 ntm = ref Tmsg.Open(tm.tag, tm.fid, tm.mode);
142 Create =>
143 t.fid = tm.fid;
144 ntm = ref Tmsg.Create(tm.tag, tm.fid, tm.name, tm.perm, tm.mode);
145 Read =>
146 t.fid = tm.fid;
147 fp := findfid(tm.fid);
148 count := tm.count;
149 offset := tm.offset;
150 if(fp.isdir){
151 count = (count/OStyx->DIRLEN)*OStyx->DIRLEN;
152 # if we got some extra entries last time,
153 # then send 'em back this time.
154 extras := fp.extras;
155 if(len extras > 0){
156 if(count > len extras)
157 count = len extras;
158 ORsend(oldclient, ref ORmsg.Read(tm.tag, t.fid, fp.extras[0:count]));
159 fp.extras = extras[count:];
160 fp.coff += count;
161 return;
162 }
163 fp.n = count;
164 if(int offset != fp.coff){
165 ORsend(oldclient, ref ORmsg.Error(tm.tag, "unexpected offset in dirread"));
166 return;
167 }
168 offset = big fp.soff;
169 }
170 ntm = ref Tmsg.Read(tm.tag, tm.fid, offset, count);
171 Write =>
172 t.fid = tm.fid;
173 ntm = ref Tmsg.Write(tm.tag, tm.fid, tm.offset, tm.data);
174 Clunk =>
175 t.fid = tm.fid;
176 ntm = ref Tmsg.Clunk(tm.tag, tm.fid);
177 Remove =>
178 t.fid = tm.fid;
179 ntm = ref Tmsg.Remove(tm.tag, tm.fid);
180 Stat =>
181 t.fid = tm.fid;
182 ntm = ref Tmsg.Stat(tm.tag, tm.fid);
183 Wstat =>
184 t.fid = tm.fid;
185 ntm = ref Tmsg.Wstat(tm.tag, tm.fid, od2nd(tm.stat));
186 * =>
187 fatal("bad T message");
188 }
189 storetag(t);
190 NTsend(newsrv, ntm);
191}
192
193# R messages: new to old
194ns2oc(t: ref Req, nrm0: ref Rmsg, oldclient: ref Sys->FD)
195{
196 rm: ref ORmsg;
197 pick nrm := nrm0{
198 Error =>
199 rm = ref ORmsg.Error(nrm.tag, nrm.ename);
200 Flush =>
201 rm = ref ORmsg.Flush(nrm.tag);
202 deletetag(t.oldtag);
203 Walk =>
204 if(len nrm.qids == 0){
205 clonefid(t.fid, t.newfid);
206 rm = ref ORmsg.Clone(nrm.tag, t.fid);
207 }else{
208 q := nrm.qids[0];
209 setfid(t.fid, q);
210 rm = ref ORmsg.Walk(nrm.tag, t.fid, nq2oq(q));
211 }
212 Open =>
213 setfid(t.fid, nrm.qid);
214 rm = ref ORmsg.Open(nrm.tag, t.fid, nq2oq(nrm.qid));
215 Create =>
216 setfid(t.fid, nrm.qid);
217 rm = ref ORmsg.Create(nrm.tag, t.fid, nq2oq(nrm.qid));
218 Read =>
219 fp := findfid(t.fid);
220 data := nrm.data;
221 if(fp != nil && fp.isdir){
222 data = nds2ods(data);
223 if(len data > fp.n){
224 fp.extras = data[fp.n:];
225 data = data[0:fp.n];
226 }
227 fp.coff += len data;
228 fp.soff += len nrm.data;
229 }
230 rm = ref ORmsg.Read(nrm.tag, t.fid, data);
231 Write =>
232 rm = ref ORmsg.Write(nrm.tag, t.fid, nrm.count);
233 Clunk =>
234 deletefid(t.fid);
235 rm = ref ORmsg.Clunk(nrm.tag, t.fid);
236 Remove =>
237 deletefid(t.fid);
238 rm = ref ORmsg.Remove(nrm.tag, t.fid);
239 Stat =>
240 rm = ref ORmsg.Stat(nrm.tag, t.fid, nd2od(nrm.stat));
241 Wstat =>
242 rm = ref ORmsg.Wstat(nrm.tag, t.fid);
243 Attach =>
244 newfid(t.fid, nrm.qid.qtype & NSys->QTDIR);
245 rm = ref ORmsg.Attach(nrm.tag, t.fid, nq2oq(nrm.qid));
246 * =>
247 fatal("bad R message");
248 }
249 ORsend(oldclient, rm);
250}
251
252storetag(t: ref Req)
253{
254 t.next = tags;
255 tags = t;
256}
257
258looktag(tag: int): ref Req
259{
260 for(t := tags; t != nil; t = t.next)
261 if(t.tag == tag)
262 return t;
263 return nil;
264}
265
266deletetag(tag: int)
267{
268 prev: ref Req;
269 t := tags;
270 while(t != nil){
271 if(t.tag == tag){
272 next := t.next;
273 t.next = nil;
274 if(prev != nil)
275 prev.next = next;
276 else
277 tags = next;
278 t = next;
279 }else{
280 prev = t;
281 t = t.next;
282 }
283 }
284}
285
286newfid(fid: int, isdir: int): ref Fid
287{
288 f := ref Fid;
289 f.fid = fid;
290 f.isdir = isdir;
291 f.n = f.soff = f.coff = 0;
292 f.next = fids;
293 fids = f;
294 return f;
295}
296
297clonefid(ofid: int, fid: int): ref Fid
298{
299 if((f := findfid(ofid)) != nil)
300 return newfid(fid, f.isdir);
301 warning("clone of non-existent fid");
302 return newfid(fid, 0);
303}
304
305deletefid(fid: int)
306{
307 lf: ref Fid;
308
309 for(f := fids; f != nil; f = f.next){
310 if(f.fid == fid){
311 if(lf == nil)
312 fids = f.next;
313 else
314 lf.next = f.next;
315 return;
316 }
317 lf = f;
318 }
319}
320
321findfid(fid: int): ref Fid
322{
323 for(f := fids; f != nil && f.fid != fid; f = f.next)
324 ;
325 return f;
326}
327
328setfid(fid: int, qid: NSys->Qid)
329{
330 if((f := findfid(fid)) != nil)
331 f.isdir = qid.qtype & NSys->QTDIR;
332}
333
334om2nm(om: int): int
335{
336 # DMDIR == CHDIR
337 return om;
338}
339
340nm2om(m: int): int
341{
342 # DMDIR == CHDIR
343 return m&~(NSys->DMAPPEND|NSys->DMEXCL|NSys->DMAUTH);
344}
345
346oq2nq(oq: OSys->Qid): NSys->Qid
347{
348 q: NSys->Qid;
349
350 isdir := oq.path&OSys->CHDIR;
351 q.path = big (oq.path&~OSys->CHDIR);
352 q.vers = oq.vers;
353 q.qtype = 0;
354 if(isdir)
355 q.qtype |= NSys->QTDIR;
356 return q;
357}
358
359nq2oq(q: NSys->Qid): OSys->Qid
360{
361 oq: OSys->Qid;
362
363 isdir := q.qtype&NSys->QTDIR;
364 oq.path = int q.path;
365 oq.vers = q.vers;
366 if(isdir)
367 oq.path |= OSys->CHDIR;
368 return oq;
369}
370
371od2nd(od: OSys->Dir): NSys->Dir
372{
373 d: NSys->Dir;
374
375 d.name = od.name;
376 d.uid = od.uid;
377 d.gid = od.gid;
378 d.muid = od.uid;
379 d.qid = oq2nq(od.qid);
380 d.mode = om2nm(od.mode);
381 d.atime = od.atime;
382 d.mtime = od.mtime;
383 d.length = big od.length;
384 d.dtype = od.dtype;
385 d.dev = od.dev;
386 return d;
387}
388
389nd2od(d: NSys->Dir): OSys->Dir
390{
391 od: OSys->Dir;
392
393 od.name = d.name;
394 od.uid = d.uid;
395 od.gid = d.gid;
396 od.qid = nq2oq(d.qid);
397 od.mode = nm2om(d.mode);
398 od.atime = d.atime;
399 od.mtime = d.mtime;
400 od.length = int d.length;
401 od.dtype = d.dtype;
402 od.dev = d.dev;
403 return od;
404}
405
406nds2ods(ob: array of byte): array of byte
407{
408 i := 0;
409 n := 0;
410 ds: list of NSys->Dir;
411 while(i < len ob){
412 (size, d) := nstyx->unpackdir(ob[i:]);
413 if(size == 0)
414 break;
415 ds = d :: ds;
416 i += size;
417 n++;
418 }
419 b := array[OStyx->DIRLEN * n] of byte;
420 for(i = (n - 1) * OStyx->DIRLEN; i >= 0; i -= OStyx->DIRLEN){
421 ostyx->convD2M(b[i:], nd2od(hd ds));
422 ds = tl ds;
423 }
424 return b;
425}
426
427NTsend(fd: ref Sys->FD, ntm: ref Tmsg)
428{
429 if(DEBUG)
430 sys->fprint(sys->fildes(2), " -> %s\n", ntm.text());
431 s := ntm.pack();
432 sys->write(fd, s, len s);
433}
434
435ORsend(fd: ref Sys->FD, orm: ref ORmsg)
436{
437 if(DEBUG)
438 sys->fprint(sys->fildes(2), "<- %s\n", ostyx->rmsg2s(orm));
439 s := array[OStyx->MAXRPC] of byte;
440 n := ostyx->rmsg2d(orm, s);
441 if(n > 0)
442 sys->write(fd, s, n);
443}
444
445readoldtmsgs(pidc: chan of int, oldclient: ref Sys->FD, oldtmsg: chan of ref OTmsg)
446{
447 pidc <-= sys->pctl(0, nil);
448 for(;;){
449 oldtmsg <-= OTmsg.read(oldclient);
450 }
451}
452
453readnewrmsgs(pidc: chan of int, newsrv: ref Sys->FD, newrmsg: chan of ref Rmsg)
454{
455 pidc <-= sys->pctl(0, nil);
456 for(;;){
457 newrmsg <-= Rmsg.read(newsrv, Msize);
458 }
459}
460
461warning(err: string)
462{
463 sys->fprint(sys->fildes(2), "warning: %s\n", err);
464}
465
466fatal(err: string)
467{
468 sys->fprint(sys->fildes(2), "%s\n", err);
469 exit;
470}
471
472nomod(mod: string, path: string)
473{
474 fatal(sys->sprint("can't load %s(%s): %r", mod, path));
475}
476
477kill(pid: int)
478{
479 sys->fprint(sys->open("#p/"+string pid+"/ctl", Sys->OWRITE), "kill");
480}
appl/lib/styxconv/ostyx.b+62−25
@@ -13,43 +13,81 @@ DEBUG: con 0; · 12 unmodified lines
13 13
14CHANHASHSIZE: con 32;14CHANHASHSIZE: con 32;
15 15
16init()
17{
18 sys = load Sys Sys->PATH;
19 gsofar = 0;
20 gdata = array[MAXRPC] of {* => byte 0};
21}
22
23# note that this implementation fails if we're reading OTmsgs and ORmsgs
24# concurrently. luckily we don't need to in styxconv.
16gsofar: int;25gsofar: int;
17gdata: array of byte;26gdata: array of byte;
18 27
19ORmsg.read(fd: ref Sys->FD, msize: int): ref ORmsg28ORmsg.read(fd: ref Sys->FD): ref ORmsg
20{29{
21 if(sys == nil)30 mlen := 0;
22 sys = load Sys Sys->PATH;31 m: ref ORmsg;
23 if(gdata == nil){
24 gsofar = 0;
25 gdata = array[msize] of byte;
26 }
27 for (;;){32 for (;;){
28 n := sys->read(fd, gdata[gsofar:], len gdata - gsofar);33 if(gsofar > 0)
29 if(n <= 0){34 (mlen, m) = d2rmsg(gdata[0 : gsofar]);
30 m: ref ORmsg = nil;35 if(mlen == 0){
31 36 if(gsofar == len gdata){
32 if(n < 0)37 ndata := array[MAXRPC] of byte;
33 m = ref ORmsg.Error(-1, sys->sprint("%r"));38 ndata[0:] = gdata;
39 gdata = ndata;
40 }
41 n := sys->read(fd, gdata[gsofar:], len gdata - gsofar);
42 if(n <= 0)
43 return nil;
44 gsofar += n;
45 }else if(mlen > 0){
46 if(tagof(m) == tagof(OTmsg.Write)) {
47 ndata := array[MAXRPC] of byte;
48 ndata[0:] = gdata[mlen : gsofar];
49 gdata = ndata;
50 }else
51 gdata[0:] = gdata[mlen : gsofar];
52 gsofar -= mlen;
34 return m;53 return m;
35 }54 }else
36 gsofar += n;
37 (cn, m) := d2rmsg(gdata[0: gsofar]);
38 if(cn == -1)
39 gsofar = 0;55 gsofar = 0;
40 else if(cn > 0){56 }
41 if(tagof(m) == tagof(ORmsg.Read)) {57}
42 ndata := array[msize] of byte;58
43 ndata[0: ] = gdata[cn: gsofar];59OTmsg.read(fd: ref Sys->FD): ref OTmsg
60{
61 mlen := 0;
62 m: ref OTmsg;
63 for (;;){
64 if(gsofar > 0)
65 (mlen, m) = d2tmsg(gdata[0 : gsofar]);
66 if(mlen == 0){
67 if(gsofar == len gdata){
68 ndata := array[MAXRPC] of byte;
69 ndata[0:] = gdata;
70 gdata = ndata;
71 }
72 n := sys->read(fd, gdata[gsofar:], len gdata - gsofar);
73 if(n <= 0)
74 return nil;
75 gsofar += n;
76 }else if(mlen > 0){
77 if(tagof(m) == tagof(OTmsg.Write)) {
78 ndata := array[MAXRPC] of byte;
79 ndata[0:] = gdata[mlen : gsofar];
44 gdata = ndata;80 gdata = ndata;
45 }else81 }else
46 gdata[0: ] = gdata[cn: gsofar];82 gdata[0:] = gdata[mlen : gsofar];
47 gsofar -= cn;83 gsofar -= mlen;
48 return m;84 return m;
49 }85 }else
86 gsofar = 0;
50 }87 }
51}88}
52 89
90
53Styxserver.new(fd: ref Sys->FD): (chan of ref OTmsg, ref Styxserver)91Styxserver.new(fd: ref Sys->FD): (chan of ref OTmsg, ref Styxserver)
54{92{
55 if (sys == nil)93 if (sys == nil)
@@ -572,7 +610,6 @@ pstring(a: array of byte, s: string, n: int): array of byte · 516 unmodified lines
572# convert from Dir to bytes610# convert from Dir to bytes
573convD2M(d: array of byte, f: OSys->Dir): array of byte611convD2M(d: array of byte, f: OSys->Dir): array of byte
574{612{
575 n := len d;
576 d = pstring(d, f.name, OSys->NAMELEN);613 d = pstring(d, f.name, OSys->NAMELEN);
577 d = pstring(d, f.uid, OSys->NAMELEN);614 d = pstring(d, f.uid, OSys->NAMELEN);
578 d = pstring(d, f.gid, OSys->NAMELEN);615 d = pstring(d, f.gid, OSys->NAMELEN);
appl/lib/styxconv/ostyx.m+3−1
@@ -24,6 +24,7 @@ OStyx: module · 23 unmodified lines
24 devclone: fn(srv: self ref Styxserver, m: ref OTmsg.Clone): ref Chan;24 devclone: fn(srv: self ref Styxserver, m: ref OTmsg.Clone): ref Chan;
25 };25 };
26 26
27 init: fn();
27 d2tmsg: fn(d: array of byte): (int, ref OTmsg);28 d2tmsg: fn(d: array of byte): (int, ref OTmsg);
28 d2rmsg: fn(d: array of byte): (int, ref ORmsg);29 d2rmsg: fn(d: array of byte): (int, ref ORmsg);
29 tmsg2d: fn(gm: ref OTmsg, d: array of byte): int;30 tmsg2d: fn(gm: ref OTmsg, d: array of byte): int;
@@ -69,6 +70,7 @@ OStyx: module · 39 unmodified lines
69 fid: int;70 fid: int;
70 uname, aname: string;71 uname, aname: string;
71 }72 }
73 read: fn(fd: ref Sys->FD): ref OTmsg;
72 };74 };
73 75
74 ORmsg: adt {76 ORmsg: adt {
@@ -99,7 +101,7 @@ OStyx: module · 24 unmodified lines
99 stat: OSys->Dir;101 stat: OSys->Dir;
100 }102 }
101 103
102 read: fn(fd: ref Sys->FD, msize: int): ref ORmsg;104 read: fn(fd: ref Sys->FD): ref ORmsg;
103 };105 };
104 106
105 MAXRPC: con 128 + OSys->ATOMICIO;107 MAXRPC: con 128 + OSys->ATOMICIO;
dis/charon.dis+0−0

Binary file not shown.

dis/charon/build.dis+0−0

Binary file not shown.

dis/charon/chutils.dis+0−0

Binary file not shown.

dis/charon/date.dis+0−0

Binary file not shown.

dis/charon/file.dis+0−0

Binary file not shown.

dis/charon/ftp.dis+0−0

Binary file not shown.

dis/charon/gui.dis+0−0

Binary file not shown.

dis/charon/http.dis+0−0

Binary file not shown.

dis/charon/img.dis+0−0

Binary file not shown.

dis/charon/jscript.dis+0−0

Binary file not shown.

dis/charon/layout.dis+0−0

Binary file not shown.

dis/charon/lex.dis+0−0

Binary file not shown.

dis/lib/styxconv/new2old.dis+0−0

Binary file not shown.

dis/lib/styxconv/old2new.dis+0−0

Binary file not shown.

dis/lib/styxconv/ostyx.dis+0−0

Binary file not shown.

dis/mount.dis+0−0

Binary file not shown.

include/version.h+1−1
@@ -1 +1 @@
1#define VERSION "Fourth Edition (20091119)"1#define VERSION "Fourth Edition (20091127)"
man/2/styxconv+28−28
@@ -4,10 +4,11 @@ styxconv \- convert between old and new Styx · 3 unmodified lines
4.SH SYNOPSIS4.SH SYNOPSIS
5.EX5.EX
6include "styxconv.m";6include "styxconv.m";
7styxconv := load Styxconv Styxconv->PATH;7styxconv := load Styxconv Styxconv->PATHNEW2OLD;
8styxconv := load Styxconv Styxconv->PATHOLD2NEW;
8 9
9init: fn();10init: fn();
10styxconv: fn(to: ref Sys->FD, from: ref Sys->FD, pid: chan of int);11styxconv: fn(client: ref Sys->FD, server: ref Sys->FD);
11.EE12.EE
12.SH DESCRIPTION13.SH DESCRIPTION
13.B Styxconv14.B Styxconv
@@ -22,49 +23,46 @@ must be called before any other function in the module. · 8 unmodified lines
22.PP23.PP
23The function24The function
24.B styxconv25.B styxconv
25takes two file descriptors.26takes two file descriptors:
26.I From27.I client
27must be a connection to a file server that serves the original, older28should be a connection to a styx client requiring
28version of Styx.29one version of the protocol;
29.I To30.I server
30is a connection, perhaps a pipe, to something that requires the current protocol;31should be a connection to a styx server serving
31.B Sys->mount32the other version of the protocol.
32for instance33There are two conversion modules:
33(see34.B PATHNEW2OLD
34.IR sys-bind (2)).35converts from a new client to an old server;
36.B PATHOLD2NEW
37converts from an old client to a new server.
38.PP
35.B Styxconv39.B Styxconv
36is spawned by the caller, to create a process that copies messages between40should be spawned by the caller, and copies messages between
37.I from41.I client
38and42and
39.IR to ,43.IR server ,
40converting as required as it goes.44converting as required.
41Its process ID is the only message sent on
42channel
43.IR pidc ;
44it must be received by
45.BR styxconv 's
46caller.
47See the example below.45See the example below.
48.SH EXAMPLE46.SH EXAMPLE
49Apply47Apply
50.B styxconv48.B styxconv
51to file descriptor49to file descriptor
52.I fd50.IR fd ,
53connected to an old Styx server:51connected to an old Styx server, and return
52a file descriptor suitable for mounting with
53.IR mount (2).
54.IP54.IP
55.EX55.EX
56cvstyx(fd: ref Sys->FD): ref Sys->FD56cvstyx(fd: ref Sys->FD): ref Sys->FD
57{57{
58 styxconv := load Styxconv Styxconv->PATH;58 styxconv := load Styxconv Styxconv->NEW2OLDPATH;
59 if(styxconv == nil)59 if(styxconv == nil)
60 return nil;60 return nil;
61 p := array[2] of ref Sys->FD;61 p := array[2] of ref Sys->FD;
62 if(sys->pipe(p) < 0)62 if(sys->pipe(p) < 0)
63 return nil;63 return nil;
64 styxconv->init();64 styxconv->init();
65 pidc := chan of int;65 spawn styxconv->styxconv(p[1], fd);
66 spawn styxconv->styxconv(p[1], fd, pidc);
67 <-pidc;
68 return p[0];66 return p[0];
69}67}
70.EE68.EE
@@ -75,3 +73,5 @@ cvstyx(fd: ref Sys->FD): ref Sys->FD · 4 unmodified lines
75.IR sys-bind (2),73.IR sys-bind (2),
76.IR sys-pipe (2),74.IR sys-pipe (2),
77.IR intro (5)75.IR intro (5)
76.SH BUGS
77There is no provision for 9p2000 authentication.
module/styxconv.m+4−3
@@ -1,9 +1,10 @@
1Styxconv: module1Styxconv: module
2{2{
3 PATH: con "/dis/lib/styxconv/styxconv.dis";3 PATHOLD2NEW: con "/dis/lib/styxconv/old2new.dis";
4 4 PATHNEW2OLD: con "/dis/lib/styxconv/new2old.dis";
5
5 # call first6 # call first
6 init: fn();7 init: fn();
7 # spawn and synchronize8 # spawn and synchronize
8 styxconv: fn(in: ref Sys->FD, out: ref Sys->FD, sync: chan of int);9 styxconv: fn(client: ref Sys->FD, server: ref Sys->FD);
9};10};
os/pc/fns.h+2−2
@@ -133,12 +133,12 @@ ulong rdtsc32(void); · 132 unmodified lines
133void screeninit(void);133void screeninit(void);
134int screenprint(char*, ...); /* debugging */134int screenprint(char*, ...); /* debugging */
135void (*screenputs)(char*, int);135void (*screenputs)(char*, int);
136#define segflush(a,n)136int segflush(void*, ulong);
137void syncclock(void);137void syncclock(void);
138uvlong tscticks(uvlong*);138uvlong tscticks(uvlong*);
139void trapenable(int, void (*)(Ureg*, void*), void*, char*);139void trapenable(int, void (*)(Ureg*, void*), void*, char*);
140void trapinit(void);140void trapinit(void);
141ulong _tas(ulong*);141int _tas(int*);
142ulong umbmalloc(ulong, int, int);142ulong umbmalloc(ulong, int, int);
143void umbfree(ulong, int);143void umbfree(ulong, int);
144ulong umbrwmalloc(ulong, int, int);144ulong umbrwmalloc(ulong, int, int);
os/pc/mmu.c+6−0
@@ -335,3 +335,9 @@ vunmap(void *va, int size) · 334 unmodified lines
335 if(va != nil)335 if(va != nil)
336 upafree(PADDR(va), size);336 upafree(PADDR(va), size);
337}337}
338
339int
340segflush(void*, ulong)
341{
342 return 0;
343}