History

20110516-2327

forsyth committed 15 years ago

Commit 7e656371 parent 20aa55d17 files · +543 −452Browse files

Unified · Split

17 files
  1. CHANGES +2 −0
  2. appl/cmd/vacfs.b +62 −50
  3. appl/cmd/vacget.b +48 −42
  4. appl/cmd/vacput.b +158 −87
  5. appl/lib/vac.b +121 −214
  6. appl/lib/venti.b +97 −4
  7. dis/lib/vac.dis +0 −0
  8. dis/lib/venti.dis +0 −0
  9. dis/vacfs.dis +0 −0
  10. dis/vacget.dis +0 −0
  11. dis/vacput.dis +0 −0
  12. include/version.h +1 −1
  13. man/1/vacget +31 −3
  14. man/2/venti +3 −7
  15. module/vac.m +17 −46
  16. module/venti.m +7 −3
  17. opt/README +1 −0
CHANGES+2−0
@@ -1,3 +1,5 @@
1+20110516
2+ merge changes from vac branch of mechiel-inferno-os (googlecode)
13 20110426
24 emu/Linux/asm-arm.S linux system call interface changed [issue 215, mechiel]
35 20110419
appl/cmd/vacfs.b+62−50
@@ -2,35 +2,36 @@ implement Vacfs; · 1 unmodified line
22
33 include "sys.m";
44 sys: Sys;
5+ sprint: import sys;
56 include "draw.m";
67 include "arg.m";
8+include "dial.m";
9+ dial: Dial;
710 include "string.m";
11+ str: String;
812 include "daytime.m";
13+ dt: Daytime;
914 include "venti.m";
15+ venti: Venti;
16+ Root, Entry, Score, Session: import venti;
17+ Roottype, Dirtype, Pointertype0, Datatype: import venti;
1018 include "vac.m";
19+ vac: Vac;
20+ Direntry, Vacdir, Vacfile: import vac;
1121 include "styx.m";
1222 styx: Styx;
1323 Tmsg, Rmsg: import styx;
1424 include "styxservers.m";
15−
16−str: String;
17−daytime: Daytime;
18−venti: Venti;
19−vac: Vac;
20−styxservers: Styxservers;
21−
22−print, sprint, fprint, fildes: import sys;
23−Score, Session: import venti;
24−Roottype, Dirtype, Pointertype0, Datatype: import venti;
25−Root, Entry, Direntry, Metablock, Metaentry, Entrysize, Modeperm, Modeappend, Modeexcl, Modedir, Modesnapshot, Vacdir, Vacfile, Source: import vac;
26−Styxserver, Fid, Navigator, Navop, Enotfound: import styxservers;
25+ styxservers: Styxservers;
26+ Styxserver, Fid, Navigator, Navop, Enotfound: import styxservers;
2727
2828 Vacfs: module {
2929 init: fn(nil: ref Draw->Context, args: list of string);
3030 };
3131
32−addr := "net!$venti!venti";
33−dflag := pflag := 0;
32+addr := "$venti";
33+dflag: int;
34+pflag: int;
3435 session: ref Session;
3536
3637 ss: ref Styxserver;
@@ -183,7 +184,7 @@ getfile(qid: int): ref Elem.File · 146 unmodified lines
183184 pick file := get(qid) {
184185 File => return file;
185186 }
186− error("internal error, getfile");
187+ fail("internal error, getfile");
187188 return nil;
188189 }
189190
@@ -192,7 +193,7 @@ getdir(qid: int): ref Elem.Dir · 2 unmodified lines
192193 pick d := get(qid) {
193194 Dir => return d;
194195 }
195− error("internal error, getdir");
196+ fail("internal error, getdir");
196197 return nil;
197198 }
198199
@@ -200,8 +201,9 @@ init(nil: ref Draw->Context, args: list of string) · 1 unmodified line
200201 {
201202 sys = load Sys Sys->PATH;
202203 arg := load Arg Arg->PATH;
204+ dial = load Dial Dial->PATH;
203205 str = load String String->PATH;
204− daytime = load Daytime Daytime->PATH;
206+ dt = load Daytime Daytime->PATH;
205207 venti = load Venti Venti->PATH;
206208 styx = load Styx Styx->PATH;
207209 styxservers = load Styxservers Styxservers->PATH;
@@ -213,7 +215,7 @@ init(nil: ref Draw->Context, args: list of string) · 5 unmodified lines
213215
214216 sys->pctl(sys->NEWPGRP, nil);
215217 if(venti == nil || vac == nil)
216− error("loading venti,vac");
218+ fail("loading venti,vac");
217219
218220 arg->init(args);
219221 arg->setusage(arg->progname()+" [-Ddp] [-a addr] [[tag:]score]");
@@ -221,11 +223,9 @@ init(nil: ref Draw->Context, args: list of string) · 1 unmodified line
221223 case ch {
222224 'D' => styxservers->traceset(1);
223225 'a' => addr = arg->earg();
224− 'd' => dflag++;
225− vac->dflag++;
226+ 'd' => vac->dflag = dflag++;
226227 'p' => pflag++;
227− * => warn(sprint("bad option: -%c", ch));
228− arg->usage();
228+ * => arg->usage();
229229 }
230230 args = arg->argv();
231231 if(len args > 1)
@@ -239,22 +239,23 @@ init(nil: ref Draw->Context, args: list of string) · 7 unmodified lines
239239 if(tag == nil)
240240 tag = "vac";
241241 if(tag != "vac")
242− error("bad score type: "+tag);
242+ fail("bad score type: "+tag);
243243 (ok, s) := Score.parse(scorestr);
244244 if(ok != 0)
245− error("bad score: "+scorestr);
245+ fail("bad score: "+scorestr);
246246 score = ref s;
247247 }
248248
249− (cok, conn) := sys->dial(addr, nil);
250− if(cok < 0)
251− error(sprint("dialing %s: %r", addr));
249+ addr = dial->netmkaddr(addr, "net", "venti");
250+ cc := dial->dial(addr, nil);
251+ if(cc == nil)
252+ fail(sprint("dialing %s: %r", addr));
252253 say("have connection");
253254
254− fd := conn.dfd;
255+ fd := cc.dfd;
255256 session = Session.new(fd);
256257 if(session == nil)
257− error(sprint("handshake: %r"));
258+ fail(sprint("handshake: %r"));
258259 say("have handshake");
259260
260261 rqid := 0;
@@ -262,14 +263,14 @@ init(nil: ref Draw->Context, args: list of string) · 1 unmodified line
262263 if(args == nil) {
263264 de := Direntry.new();
264265 de.uid = de.gid = de.mid = user();
265− de.ctime = de.atime = de.mtime = daytime->now();
266+ de.ctime = de.atime = de.mtime = dt->now();
266267 de.mode = Vac->Modedir|8r755;
267268 de.emode = Sys->DMDIR|8r755;
268269 red = ref Elem.Dir(rqid, de, big 0, nil, rqid, 0, 0, nil);
269270 } else {
270271 (vd, de, err) := vac->vdroot(session, *score);
271272 if(err != nil)
272− error(err);
273+ fail(err);
273274 rqid = ++lastqid;
274275 red = ref Elem.Dir(rqid, de, big 0, vd, rqid, 0, 0, nil);
275276 }
@@ -284,12 +285,16 @@ init(nil: ref Draw->Context, args: list of string) · 8 unmodified lines
284285 (msgc, ss) = Styxserver.new(sys->fildes(0), nav, big rqid);
285286
286287 for(;;) {
287− pick m := <- msgc {
288+ mm := <-msgc;
289+ if(mm == nil)
290+ fail("eof");
291+
292+ pick m := mm {
288293 Readerror =>
289− say("read error: "+m.error);
294+ fail("read error: "+m.error);
290295
291296 Read =>
292− say(sprint("have read, offset=%ubd count=%d", m.offset, m.count));
297+ if(dflag) say(sprint("have read, offset=%ubd count=%d", m.offset, m.count));
293298 (c, err) := ss.canread(m);
294299 if(c == nil){
295300 ss.reply(ref Rmsg.Error(m.tag, err));
@@ -353,14 +358,14 @@ navigator(c: chan of ref Navop) · 57 unmodified lines
353358 loop:
354359 for(;;) {
355360 navop := <- c;
356− say(sprint("have navop, path=%bd", navop.path));
361+ if(dflag) say(sprint("have navop, path=%bd", navop.path));
357362 pick n := navop {
358363 Stat =>
359− say(sprint("have stat"));
364+ if(dflag) say(sprint("have stat"));
360365 n.reply <-= (get(int n.path).stat(), nil);
361366
362367 Walk =>
363− say(sprint("have walk, name=%q", n.name));
368+ if(dflag) say(sprint("have walk, name=%q", n.name));
364369 ed := getdir(int n.path);
365370 (ne, err) := walk(ed, n.name);
366371 if(err != nil) {
@@ -370,7 +375,7 @@ loop: · 3 unmodified lines
370375 n.reply <-= (ne.stat(), nil);
371376
372377 Readdir =>
373− say(sprint("have readdir path=%bd offset=%d count=%d", n.path, n.offset, n.count));
378+ if(dflag) say(sprint("have readdir path=%bd offset=%d count=%d", n.path, n.offset, n.count));
374379 if(n.path == big 0) {
375380 n.reply <-= (nil, nil);
376381 break;
@@ -423,22 +428,21 @@ loop: · 46 unmodified lines
423428
424429 user(): string
425430 {
426− if((fd := sys->open("/dev/user", Sys->OREAD)) != nil
427− && (n := sys->read(fd, d := array[128] of byte, len d)) > 0)
431+ fd := sys->open("/dev/user", Sys->OREAD);
432+ if(fd != nil)
433+ if((n := sys->read(fd, d := array[128] of byte, len d)) > 0)
428434 return string d[:n];
429435 return "nobody";
430436 }
431437
432−error(s: string)
438+pid(): int
433439 {
434− killgrp();
435− fprint(fildes(2), "%s\n", s);
436− raise "fail:"+s;
440+ return sys->pctl(0, nil);
437441 }
438442
439−warn(s: string)
443+killgrp(pid: int)
440444 {
441− fprint(fildes(2), "%s\n", s);
445+ sys->fprint(sys->open(sprint("/prog/%d/ctl", pid), sys->OWRITE), "killgrp");
442446 }
443447
444448 say(s: string)
@@ -447,9 +451,17 @@ say(s: string) · 2 unmodified lines
447451 warn(s);
448452 }
449453
450−killgrp()
454+fd2: ref Sys->FD;
455+warn(s: string)
451456 {
452− fd := sys->open("/prog/"+string sys->pctl(0, nil)+"/ctl", sys->OWRITE);
453− if(fd != nil)
454− sys->fprint(fd, "killgrp\n");
457+ if(fd2 == nil)
458+ fd2 = sys->fildes(2);
459+ sys->fprint(fd2, "%s\n", s);
460+}
461+
462+fail(s: string)
463+{
464+ warn(s);
465+ killgrp(pid());
466+ raise "fail:"+s;
455467 }
appl/cmd/vacget.b+48−42
@@ -2,30 +2,33 @@ implement Vacget; · 1 unmodified line
22
33 include "sys.m";
44 sys: Sys;
5+ sprint: import sys;
56 include "draw.m";
67 include "bufio.m";
78 bufio: Bufio;
89 Iobuf: import bufio;
910 include "arg.m";
11+include "dial.m";
12+ dial: Dial;
1013 include "string.m";
14+ str: String;
1115 include "venti.m";
16+ venti: Venti;
17+ Root, Entry, Score, Session: import venti;
1218 include "vac.m";
13−
14−str: String;
15−venti: Venti;
16−vac: Vac;
17−
18−print, sprint, fprint, fildes: import sys;
19−Score, Session: import venti;
20−Roottype, Dirtype, Pointertype0, Datatype: import venti;
21−Root, Entry, Direntry, Metablock, Metaentry, Entrysize, Modeperm, Modeappend, Modeexcl, Modedir, Modesnapshot, Vacdir, Vacfile, Source: import vac;
19+ vac: Vac;
20+ Direntry, Vacdir, Vacfile: import vac;
2221
2322 Vacget: module {
2423 init: fn(nil: ref Draw->Context, args: list of string);
2524 };
2625
27−addr := "net!$venti!venti";
28−dflag := vflag := pflag := tflag := 0;
26+addr := "$venti";
27+dflag: int;
28+vflag: int;
29+pflag: int;
30+tflag: int;
31+
2932 session: ref Session;
3033
3134 init(nil: ref Draw->Context, args: list of string)
@@ -33,26 +36,25 @@ init(nil: ref Draw->Context, args: list of string) · 1 unmodified line
3336 sys = load Sys Sys->PATH;
3437 bufio = load Bufio Bufio->PATH;
3538 arg := load Arg Arg->PATH;
39+ dial = load Dial Dial->PATH;
3640 str = load String String->PATH;
3741 venti = load Venti Venti->PATH;
3842 vac = load Vac Vac->PATH;
3943 if(venti == nil || vac == nil)
40− error("loading venti,vac");
44+ fail("loading venti,vac");
4145 venti->init();
4246 vac->init();
4347
4448 arg->init(args);
45− arg->setusage(sprint("%s [-dtv] [-a addr] [tag:]score", arg->progname()));
49+ arg->setusage(arg->progname()+" [-dtv] [-a addr] [tag:]score");
4650 while((c := arg->opt()) != 0)
4751 case c {
4852 'a' => addr = arg->earg();
49− 'd' => dflag++;
50− vac->dflag++;
53+ 'd' => vac->dflag = dflag++;
5154 'p' => pflag++;
5255 't' => tflag++;
5356 'v' => vflag++;
54− * => warn(sprint("bad option: -%c", c));
55− arg->usage();
57+ * => arg->usage();
5658 }
5759 args = arg->argv();
5860 if(len args != 1)
@@ -64,27 +66,28 @@ init(nil: ref Draw->Context, args: list of string) · 5 unmodified lines
6466 if(tag == nil)
6567 tag = "vac";
6668 if(tag != "vac")
67− error("bad score type: "+tag);
69+ fail("bad score type: "+tag);
6870
6971 (sok, score) := Score.parse(scorestr);
7072 if(sok != 0)
71− error("bad score: "+scorestr);
73+ fail("bad score: "+scorestr);
7274 say("have score");
7375
74− (cok, conn) := sys->dial(addr, nil);
75− if(cok < 0)
76− error(sprint("dialing %s: %r", addr));
76+ addr = dial->netmkaddr(addr, "net", "venti");
77+ cc := dial->dial(addr, nil);
78+ if(cc == nil)
79+ fail(sprint("dialing %s: %r", addr));
7780 say("have connection");
7881
79− fd := conn.dfd;
82+ fd := cc.dfd;
8083 session = Session.new(fd);
8184 if(session == nil)
82− error(sprint("handshake: %r"));
85+ fail(sprint("handshake: %r"));
8386 say("have handshake");
8487
8588 (vd, nil, err) := vac->vdroot(session, score);
8689 if(err != nil)
87− error(err);
90+ fail(err);
8891
8992 say("starting walk");
9093 walk(".", vd);
@@ -120,21 +123,21 @@ walk(path: string, vd: ref Vacdir) · 29 unmodified lines
120123 for(;;) {
121124 (n, de) := vd.readdir();
122125 if(n < 0)
123− error(sprint("reading direntry in %s: %r", path));
126+ fail(sprint("reading direntry in %s: %r", path));
124127 if(n == 0)
125128 break;
126− say("walk: have direntry, elem="+de.elem);
129+ if(dflag) say("walk: have direntry, elem="+de.elem);
127130 newpath := path+"/"+de.elem;
128131 (e, me) := vd.open(de);
129132 if(e == nil)
130− error(sprint("reading entry for %s: %r", newpath));
133+ fail(sprint("reading entry for %s: %r", newpath));
131134
132− oflags := de.mode&~(Modeperm|Modeappend|Modeexcl|Modedir|Modesnapshot);
135+ oflags := de.mode&~(vac->Modeperm|vac->Modeappend|vac->Modeexcl|vac->Modedir|vac->Modesnapshot);
133136 if(oflags)
134137 warn(sprint("%s: not all bits in mode can be set: 0x%x", newpath, oflags));
135138
136139 if(tflag || vflag)
137− print("%s\n", newpath);
140+ sys->print("%s\n", newpath);
138141
139142 if(me != nil) {
140143 if(!tflag)
@@ -148,10 +151,10 @@ walk(path: string, vd: ref Vacdir) · 7 unmodified lines
148151 say("writing file");
149152 fd := create(newpath, sys->OWRITE, de);
150153 if(fd == nil)
151− error(sprint("creating %s: %r", newpath));
154+ fail(sprint("creating %s: %r", newpath));
152155 bio := bufio->fopen(fd, bufio->OWRITE);
153156 if(bio == nil)
154− error(sprint("bufio fopen %s: %r", newpath));
157+ fail(sprint("bufio fopen %s: %r", newpath));
155158
156159 buf := array[sys->ATOMICIO] of byte;
157160 vf := Vacfile.new(session, e);
@@ -160,15 +163,15 @@ walk(path: string, vd: ref Vacdir) · 2 unmodified lines
160163 if(rn == 0)
161164 break;
162165 if(rn < 0)
163− error(sprint("reading vac %s: %r", newpath));
166+ fail(sprint("reading vac %s: %r", newpath));
164167 wn := bio.write(buf, rn);
165168 if(wn != rn)
166− error(sprint("writing local %s: %r", newpath));
169+ fail(sprint("writing local %s: %r", newpath));
167170 }
168171 bok := bio.flush();
169172 bio.close();
170173 if(bok == bufio->ERROR || bok == bufio->EOF)
171− error(sprint("bufio close: %r"));
174+ fail(sprint("bufio close: %r"));
172175
173176 if(pflag) {
174177 d := sys->nulldir;
@@ -181,19 +184,22 @@ walk(path: string, vd: ref Vacdir) · 6 unmodified lines
181184 }
182185 }
183186
184−error(s: string)
187+say(s: string)
185188 {
186− fprint(fildes(2), "%s\n", s);
187− raise "fail:"+s;
189+ if(dflag)
190+ warn(s);
188191 }
189192
193+fd2: ref Sys->FD;
190194 warn(s: string)
191195 {
192− fprint(fildes(2), "%s\n", s);
196+ if(fd2 == nil)
197+ fd2 = sys->fildes(2);
198+ sys->fprint(fd2, "%s\n", s);
193199 }
194200
195−say(s: string)
201+fail(s: string)
196202 {
197− if(dflag)
198− warn(s);
203+ warn(s);
204+ raise "fail:"+s;
199205 }
appl/cmd/vacput.b+158−87
@@ -2,81 +2,113 @@ implement Vacput; · 1 unmodified line
22
33 include "sys.m";
44 sys: Sys;
5+ sprint: import sys;
56 include "draw.m";
7+include "arg.m";
68 include "daytime.m";
9+ dt: Daytime;
710 include "bufio.m";
811 bufio: Bufio;
912 Iobuf: import bufio;
10−include "arg.m";
13+include "dial.m";
14+ dial: Dial;
1115 include "string.m";
16+ str: String;
17+include "tables.m";
18+ tables: Tables;
19+ Strhash: import tables;
1220 include "venti.m";
21+ venti: Venti;
22+ Root, Entry, Score, Session: import venti;
1323 include "vac.m";
14−
15−daytime: Daytime;
16−str: String;
17−venti: Venti;
18−vac: Vac;
19−
20−print, sprint, fprint, fildes: import sys;
21−Score, Session: import venti;
22−Roottype, Dirtype, Pointertype0, Datatype: import venti;
23−Root, Entry, Direntry, Metablock, Metaentry, Entrysize, File, Sink, MSink: import vac;
24+ vac: Vac;
25+ Direntry, File, Sink, MSink: import vac;
2426
2527 Vacput: module {
2628 init: fn(nil: ref Draw->Context, args: list of string);
2729 };
2830
29−addr := "net!$venti!venti";
30−dflag := 0;
31−vflag := 0;
31+addr := "$venti";
32+dflag: int;
33+iflag: int;
34+vflag: int;
35+xflag: int;
3236 blocksize := vac->Dsize;
37+uid: string;
38+gid: string;
39+
40+pathgen: big;
41+
42+bout: ref Iobuf;
3343 session: ref Session;
3444 name := "vac";
45+itab,
46+xtab: ref Strhash[string]; # include/exclude paths
3547
3648 init(nil: ref Draw->Context, args: list of string)
3749 {
3850 sys = load Sys Sys->PATH;
39− daytime = load Daytime Daytime->PATH;
51+ dt = load Daytime Daytime->PATH;
4052 bufio = load Bufio Bufio->PATH;
4153 arg := load Arg Arg->PATH;
54+ dial = load Dial Dial->PATH;
4255 str = load String String->PATH;
56+ tables = load Tables Tables->PATH;
4357 venti = load Venti Venti->PATH;
4458 vac = load Vac Vac->PATH;
4559 if(venti == nil || vac == nil)
46− error("loading venti,vac");
60+ fail("loading venti,vac");
4761 venti->init();
4862 vac->init();
4963
5064 arg->init(args);
51− arg->setusage(sprint("%s [-dtv] [-a addr] [-b blocksize] [-n name] path ...", arg->progname()));
65+ arg->setusage(arg->progname()+" [-dv] [-i | -x] [-a addr] [-b blocksize] [-n name] [-u uid] [-g gid] path ...");
5266 while((c := arg->opt()) != 0)
5367 case c {
5468 'a' => addr = arg->earg();
5569 'b' => blocksize = int arg->earg();
5670 'n' => name = arg->earg();
57− 'd' => dflag++;
58− vac->dflag++;
71+ 'd' => vac->dflag = dflag++;
72+ 'i' => iflag++;
5973 'v' => vflag++;
60− * => warn(sprint("bad option: -%c", c));
61− arg->usage();
74+ 'x' => xflag++;
75+ 'g' => gid = arg->earg();
76+ 'u' => uid = arg->earg();
77+ * => arg->usage();
6278 }
6379 args = arg->argv();
6480 if(len args == 0)
6581 arg->usage();
82+ if(iflag && xflag) {
83+ warn("cannot have both -i and -x");
84+ arg->usage();
85+ }
6686
67− (cok, conn) := sys->dial(addr, nil);
68− if(cok < 0)
69− error(sprint("dialing %s: %r", addr));
87+ if(vflag)
88+ bout = bufio->fopen(sys->fildes(1), bufio->OWRITE);
89+
90+ if(iflag || xflag) {
91+ t := readpaths();
92+ if(iflag)
93+ itab = t;
94+ else
95+ xtab = t;
96+ }
97+
98+ addr = dial->netmkaddr(addr, "net", "venti");
99+ cc := dial->dial(addr, nil);
100+ if(cc == nil)
101+ fail(sprint("dialing %s: %r", addr));
70102 say("have connection");
71103
72− fd := conn.dfd;
104+ fd := cc.dfd;
73105 session = Session.new(fd);
74106 if(session == nil)
75− error(sprint("handshake: %r"));
107+ fail(sprint("handshake: %r"));
76108 say("have handshake");
77109
78110 topde: ref Direntry;
79− if(len args == 1 && ((nil, d) := sys->stat(hd args)).t0 == 0 && d.mode&Sys->DMDIR) {
111+ if(len args == 1 && ((nil, d) := sys->stat(hd args)).t0 == 0 && (d.mode&Sys->DMDIR)) {
80112 topde = Direntry.mk(d);
81113 topde.elem = name;
82114 } else {
@@ -86,7 +118,12 @@ init(nil: ref Draw->Context, args: list of string) · 3 unmodified lines
86118 topde.mode = 8r777|Vac->Modedir;
87119 topde.mtime = topde.atime = 0;
88120 }
89− topde.ctime = daytime->now();
121+ topde.qid = pathgen++;
122+ if(uid != nil)
123+ topde.uid = uid;
124+ if(gid != nil)
125+ topde.gid = gid;
126+ topde.ctime = dt->now();
90127
91128 s := Sink.new(session, blocksize);
92129 ms := MSink.new(session, blocksize);
@@ -94,66 +131,93 @@ init(nil: ref Draw->Context, args: list of string) · 1 unmodified line
94131 writepath(hd args, s, ms);
95132 say("tree written");
96133
134+ if(vflag && bout.flush() == bufio->ERROR)
135+ fail(sprint("write stdout: %r"));
136+
97137 e0 := s.finish();
98138 if(e0 == nil)
99− error(sprint("writing top entry: %r"));
139+ fail(sprint("writing top entry: %r"));
100140 e1 := ms.finish();
101141 if(e1 == nil)
102− error(sprint("writing top meta entry: %r"));
103− say(sprint("top entries written (%s, %s)", e0.score.text(), e1.score.text()));
142+ fail(sprint("writing top meta entry: %r"));
143+ topde.qidspace = 1;
144+ topde.qidoff = big 0;
145+ topde.qidmax = pathgen;
104146 s2 := MSink.new(session, blocksize);
105147 if(s2.add(topde) < 0)
106− error(sprint("adding direntry for top entries: %r"));
148+ fail(sprint("adding direntry for top entries: %r"));
107149 e2 := s2.finish();
108150 say("top meta entry written, "+e2.score.text());
109151
110− td := array[Entrysize*3] of byte;
111− td[0*Entrysize:] = e0.pack();
112− td[1*Entrysize:] = e1.pack();
113− td[2*Entrysize:] = e2.pack();
114− (tok, tscore) := session.write(Dirtype, td);
152+ td := array[venti->Entrysize*3] of byte;
153+ td[0*venti->Entrysize:] = e0.pack();
154+ td[1*venti->Entrysize:] = e1.pack();
155+ td[2*venti->Entrysize:] = e2.pack();
156+ (tok, tscore) := session.write(venti->Dirtype, td);
115157 if(tok < 0)
116− error(sprint("writing top-level entries: %r"));
117− say("top entry written, "+tscore.text());
158+ fail(sprint("writing top-level entries: %r"));
118159
119− root := Root.new(name, "vac", tscore, blocksize, nil);
160+ root := ref Root(venti->Rootversion, name, "vac", tscore, blocksize, nil);
120161 rd := root.pack();
121162 if(rd == nil)
122− error(sprint("root pack: %r"));
123− (rok, rscore) := session.write(Roottype, rd);
163+ fail(sprint("root pack: %r"));
164+ (rok, rscore) := session.write(venti->Roottype, rd);
124165 if(rok < 0)
125− error(sprint("writing root score: %r"));
126− say("root written, "+rscore.text());
127− print("vac:%s\n", rscore.text());
166+ fail(sprint("writing root score: %r"));
167+ sys->print("vac:%s\n", rscore.text());
128168 if(session.sync() < 0)
129− error(sprint("syncing server: %r"));
169+ fail(sprint("syncing server: %r"));
170+}
171+
172+readpaths(): ref Strhash[string]
173+{
174+ t := Strhash[string].new(199, nil);
175+ b := bufio->fopen(sys->fildes(0), bufio->OREAD);
176+ if(b == nil)
177+ fail(sprint("fopen: %r"));
178+ for(;;) {
179+ s := b.gets('\n');
180+ if(s == nil)
181+ break;
182+ if(s[len s-1] == '\n')
183+ s = s[:len s-1];
184+ t.add(s, s);
185+ }
186+ return t;
187+}
188+
189+usepath(p: string): int
190+{
191+ if(itab != nil)
192+ return itab.find(p) != nil;
193+ if(xtab != nil)
194+ return xtab.find(p) == nil;
195+ return 1;
130196 }
131197
132198 writepath(path: string, s: ref Sink, ms: ref MSink)
133199 {
134− if(vflag)
135− print("%s\n", path);
136−say("writepath "+path);
200+ if(!usepath(path))
201+ return;
202+
203+ if(vflag && bout.puts(path+"\n") == bufio->ERROR)
204+ fail(sprint("write stdout: %r"));
205+
137206 fd := sys->open(path, sys->OREAD);
138207 if(fd == nil)
139− error(sprint("opening %s: %r", path));
208+ fail(sprint("opening %s: %r", path));
140209 (ok, dir) := sys->fstat(fd);
141210 if(ok < 0)
142− error(sprint("fstat %s: %r", path));
143−say("writepath: file opened");
144− if(dir.mode&sys->DMAUTH) {
145− warn(path+": is auth file, skipping");
146− return;
147− }
148− if(dir.mode&sys->DMTMP) {
149− warn(path+": is temporary file, skipping");
150− return;
151− }
211+ fail(sprint("fstat %s: %r", path));
212+ if(dir.mode&sys->DMAUTH)
213+ return warn(path+": is auth file, skipping");
214+ if(dir.mode&sys->DMTMP)
215+ return warn(path+": is temporary file, skipping");
152216
153217 e, me: ref Entry;
154218 de: ref Direntry;
219+ qid := pathgen++;
155220 if(dir.mode & sys->DMDIR) {
156−say("writepath: file is dir");
157221 ns := Sink.new(session, blocksize);
158222 nms := MSink.new(session, blocksize);
159223 for(;;) {
@@ -161,7 +225,7 @@ say("writepath: file is dir"); · 1 unmodified line
161225 if(n == 0)
162226 break;
163227 if(n < 0)
164− error(sprint("dirread %s: %r", path));
228+ fail(sprint("dirread %s: %r", path));
165229 for(i := 0; i < len dirs; i++) {
166230 d := dirs[i];
167231 npath := path+"/"+d.name;
@@ -170,45 +234,49 @@ say("writepath: file is dir"); · 2 unmodified lines
170234 }
171235 e = ns.finish();
172236 if(e == nil)
173− error(sprint("error flushing dirsink for %s: %r", path));
237+ fail(sprint("error flushing dirsink for %s: %r", path));
174238 me = nms.finish();
175239 if(me == nil)
176− error(sprint("error flushing metasink for %s: %r", path));
240+ fail(sprint("error flushing metasink for %s: %r", path));
177241 } else {
178−say("writepath: file is normale file");
179242 e = writefile(path, fd);
180243 if(e == nil)
181− error(sprint("error flushing filesink for %s: %r", path));
244+ fail(sprint("error flushing filesink for %s: %r", path));
182245 }
183−say("writepath: wrote path, "+e.score.text());
184246
247+ case dir.name {
248+ "/" => dir.name = "root";
249+ "." => dir.name = "dot";
250+ }
185251 de = Direntry.mk(dir);
186−say("writepath: have direntry");
252+ de.qid = qid;
253+ if(uid != nil)
254+ de.uid = uid;
255+ if(gid != nil)
256+ de.gid = gid;
187257
188258 i := s.add(e);
189259 if(i < 0)
190− error(sprint("adding entry to sink: %r"));
260+ fail(sprint("adding entry to sink: %r"));
191261 mi := 0;
192262 if(me != nil)
193263 mi = s.add(me);
194264 if(mi < 0)
195− error(sprint("adding mentry to sink: %r"));
265+ fail(sprint("adding mentry to sink: %r"));
196266 de.entry = i;
197267 de.mentry = mi;
198268 i = ms.add(de);
199269 if(i < 0)
200− error(sprint("adding direntry to msink: %r"));
201−say("writepath done");
270+ fail(sprint("adding direntry to msink: %r"));
202271 }
203272
204273 writefile(path: string, fd: ref Sys->FD): ref Entry
205274 {
206275 bio := bufio->fopen(fd, bufio->OREAD);
207276 if(bio == nil)
208− error(sprint("bufio opening %s: %r", path));
209− say(sprint("bufio opened path %s", path));
277+ fail(sprint("bufio opening %s: %r", path));
210278
211− f := File.new(session, Datatype, blocksize);
279+ f := File.new(session, venti->Datatype, blocksize);
212280 for(;;) {
213281 buf := array[blocksize] of byte;
214282 n := 0;
@@ -218,13 +286,12 @@ writefile(path: string, fd: ref Sys->FD): ref Entry · 3 unmodified lines
218286 if(have == 0)
219287 break;
220288 if(have < 0)
221− error(sprint("reading %s: %r", path));
289+ fail(sprint("reading %s: %r", path));
222290 n += have;
223291 }
224− say(sprint("have buf, length %d", n));
225292
226293 if(f.write(buf[:n]) < 0)
227− error(sprint("writing %s: %r", path));
294+ fail(sprint("writing %s: %r", path));
228295 if(n != len buf)
229296 break;
230297 }
@@ -234,21 +301,19 @@ writefile(path: string, fd: ref Sys->FD): ref Entry · 3 unmodified lines
234301
235302 user(): string
236303 {
237− if((fd := sys->open("/dev/user", Sys->OREAD)) != nil
238− && (n := sys->read(fd, d := array[128] of byte, len d)) > 0)
304+ fd := sys->open("/dev/user", Sys->OREAD);
305+ if(fd != nil)
306+ if((n := sys->read(fd, d := array[128] of byte, len d)) > 0)
239307 return string d[:n];
240308 return "nobody";
241309 }
242310
243−error(s: string)
244−{
245− warn(s);
246− raise "fail:"+s;
247−}
248−
311+fd2: ref Sys->FD;
249312 warn(s: string)
250313 {
251− fprint(fildes(2), "%s\n", s);
314+ if(fd2 == nil)
315+ fd2 = sys->fildes(2);
316+ sys->fprint(fd2, "%s\n", s);
252317 }
253318
254319 say(s: string)
@@ -256,3 +321,9 @@ say(s: string) · 1 unmodified line
256321 if(dflag)
257322 warn(s);
258323 }
324+
325+fail(s: string)
326+{
327+ warn(s);
328+ raise "fail:"+s;
329+}
appl/lib/vac.b+121−214
@@ -1,19 +1,17 @@
11 implement Vac;
22
33 include "sys.m";
4+ sys: Sys;
5+ sprint: import sys;
46 include "venti.m";
7+ venti: Venti;
8+ Entrysize, Scoresize, Roottype, Dirtype, Pointertype0, Datatype: import venti;
9+ Root, Entry, Score, Session: import venti;
510 include "vac.m";
611
7−sys: Sys;
8−venti: Venti;
9−
10−werrstr, sprint, fprint, fildes: import sys;
11−Roottype, Dirtype, Pointertype0, Datatype: import venti;
12−Score, Session, Scoresize: import venti;
1312
1413 dflag = 0;
1514
16−# from venti.b
1715 BIT8SZ: con 1;
1816 BIT16SZ: con 2;
1917 BIT32SZ: con 4;
@@ -32,7 +30,6 @@ blankdirentry: Direntry; · 12 unmodified lines
3230 blankmetablock: Metablock;
3331 blankmetaentry: Metaentry;
3432
35−
3633 init()
3734 {
3835 sys = load Sys Sys->PATH;
@@ -40,158 +37,9 @@ init() · 1 unmodified line
4037 venti->init();
4138 }
4239
43−pstring(a: array of byte, o: int, s: string): int
44−{
45− sa := array of byte s; # could do conversion ourselves
46− n := len sa;
47− a[o] = byte (n >> 8);
48− a[o+1] = byte n;
49− a[o+2:] = sa;
50− return o+BIT16SZ+n;
51−}
52−
53−gstring(a: array of byte, o: int): (string, int)
54−{
55− if(o < 0 || o+BIT16SZ > len a)
56− return (nil, -1);
57− l := (int a[o] << 8) | int a[o+1];
58− if(l > Maxstringsize)
59− return (nil, -1);
60− o += BIT16SZ;
61− e := o+l;
62− if(e > len a)
63− return (nil, -1);
64− return (string a[o:e], e);
65−}
66−
67−gtstring(a: array of byte, o: int, n: int): string
68−{
69− e := o + n;
70− if(e > len a)
71− return nil;
72− for(i := o; i < e; i++)
73− if(a[i] == byte 0)
74− break;
75− return string a[o:i];
76−}
77−
78−
79−Root.new(name, rtype: string, score: Score, blocksize: int, prev: ref Score): ref Root
80−{
81− return ref Root(Rootversion, name, rtype, score, blocksize, prev);
82−}
83−
84−Root.pack(r: self ref Root): array of byte
85−{
86− d := array[Rootsize] of byte;
87− i := 0;
88− i = p16(d, i, r.version);
89− i = ptstring(d, i, r.name, Rootnamelen);
90− if(i < 0)
91− return nil;
92− i = ptstring(d, i, r.rtype, Rootnamelen);
93− if(i < 0)
94− return nil;
95− i = pscore(d, i, r.score);
96− i = p16(d, i, r.blocksize);
97− if(r.prev == nil) {
98− for(j := 0; j < Scoresize; j++)
99− d[i+j] = byte 0;
100− i += Scoresize;
101− } else
102− i = pscore(d, i, *r.prev);
103− if(i != len d) {
104− sys->werrstr("root pack, bad length: "+string i);
105− return nil;
106− }
107− return d;
108−}
109−
110−Root.unpack(d: array of byte): ref Root
111−{
112− if(len d != Rootsize){
113− sys->werrstr("root entry is wrong length");
114− return nil;
115− }
116− r := ref blankroot;
117− r.version = g16(d, 0);
118− if(r.version != Rootversion){
119− sys->werrstr("unknown root version");
120− return nil;
121− }
122− o := BIT16SZ;
123− r.name = gtstring(d, o, Rootnamelen);
124− o += Rootnamelen;
125− r.rtype = gtstring(d, o, Rootnamelen);
126− o += Rootnamelen;
127− r.score = gscore(d, o);
128− o += Scoresize;
129− r.blocksize = g16(d, o);
130− o += BIT16SZ;
131− r.prev = ref gscore(d, o);
132− return r;
133−}
134−
135−Entry.new(psize, dsize, flags: int, size: big, score: Venti->Score): ref Entry
136−{
137− return ref Entry(0, psize, dsize, (flags&Entrydepthmask)>>Entrydepthshift, flags, size, score);
138−}
139−
140−Entry.pack(e: self ref Entry): array of byte
141−{
142− d := array[Entrysize] of byte;
143− i := 0;
144− i = p32(d, i, e.gen);
145− i = p16(d, i, e.psize);
146− i = p16(d, i, e.dsize);
147− e.flags |= e.depth<<Entrydepthshift;
148− d[i++] = byte e.flags;
149− for(j := 0; j < 5; j++)
150− d[i++] = byte 0;
151− i = p48(d, i, e.size);
152− i = pscore(d, i, e.score);
153− if(i != len d) {
154− werrstr(sprint("bad length, have %d, want %d", i, len d));
155− return nil;
156− }
157− return d;
158−}
159−
160−Entry.unpack(d: array of byte): ref Entry
161−{
162− if(len d != Entrysize){
163− sys->werrstr("entry is wrong length");
164− return nil;
165− }
166− e := ref blankentry;
167− i := 0;
168− e.gen = g32(d, i);
169− i += BIT32SZ;
170− e.psize = g16(d, i);
171− i += BIT16SZ;
172− e.dsize = g16(d, i);
173− i += BIT16SZ;
174− e.flags = int d[i];
175− e.depth = (e.flags & Entrydepthmask) >> Entrydepthshift;
176− e.flags &= ~Entrydepthmask;
177− i += BIT8SZ;
178− i += 5; # skip something...
179− e.size = g48(d, i);
180− i += BIT48SZ;
181− e.score = gscore(d, i);
182− i += Scoresize;
183− if((e.flags & Entryactive) == 0)
184− return e;
185− if(!checksize(e.psize) || !checksize(e.dsize)){
186− sys->werrstr(sys->sprint("bad blocksize (%d or %d)", e.psize, e.dsize));
187− return nil;
188− }
189− return e;
190−}
191−
19240 Direntry.new(): ref Direntry
19341 {
194− return ref Direntry(9, "", 0, 0, 0, 0, big 0, "", "", "", 0, 0, 0, 0, 0, 0);
42+ return ref Direntry(9, "", 0, 0, 0, 0, big 0, "", "", "", 0, 0, 0, 0, 0, 0, 0, big 0, big 0);
19543 }
19644
19745 Direntry.mk(d: Sys->Dir): ref Direntry
@@ -206,7 +54,7 @@ Direntry.mk(d: Sys->Dir): ref Direntry · 8 unmodified lines
20654 mode |= Modedir;
20755 if(d.mode&sys->DMTMP)
20856 mode |= Modetemp;
209− return ref Direntry(9, d.name, 0, 0, 0, 0, d.qid.path, d.uid, d.gid, d.muid, d.mtime, 0, 0, atime, mode, d.mode);
57+ return ref Direntry(9, d.name, 0, 0, 0, 0, d.qid.path, d.uid, d.gid, d.muid, d.mtime, 0, 0, atime, mode, d.mode, 0, big 0, big 0);
21058 }
21159
21260 Direntry.mkdir(de: self ref Direntry): ref Sys->Dir
@@ -233,8 +81,14 @@ strlen(s: string): int · 20 unmodified lines
23381
23482 Direntry.pack(de: self ref Direntry): array of byte
23583 {
236− # assume version 9
237− length := 4+2+strlen(de.elem)+4+4+4+4+8+strlen(de.uid)+strlen(de.gid)+strlen(de.mid)+4+4+4+4+4; # + qidspace?
84+ if(de.version != 9) {
85+ sys->werrstr("only version 9 supported");
86+ return nil;
87+ }
88+
89+ length := 4+2+strlen(de.elem)+4+4+4+4+8+strlen(de.uid)+strlen(de.gid)+strlen(de.mid)+4+4+4+4+4;
90+ if(de.qidspace)
91+ length += 1+2+8+8;
23892
23993 d := array[length] of byte;
24094 i := 0;
@@ -256,8 +110,14 @@ Direntry.pack(de: self ref Direntry): array of byte · 15 unmodified lines
256110 i = p32(d, i, de.ctime);
257111 i = p32(d, i, de.atime);
258112 i = p32(d, i, de.mode);
113+ if(de.qidspace) {
114+ d[i++] = byte DirQidspace;
115+ i = p16(d, i, 16);
116+ i = p64(d, i, de.qidoff);
117+ i = p64(d, i, de.qidmax);
118+ }
259119 if(i != len d) {
260− werrstr(sprint("bad length for direntry (expected %d, have %d)", len d, i));
120+ sys->werrstr(sprint("bad length for direntry (expected %d, have %d)", len d, i));
261121 return nil;
262122 }
263123 return d;
@@ -271,12 +131,12 @@ Direntry.unpack(d: array of byte): ref Direntry · 7 unmodified lines
271131 magic: int;
272132 (magic, i) = eg32(d, i);
273133 if(magic != Direntrymagic) {
274− werrstr(sprint("bad magic (%x, want %x)", magic, Direntrymagic));
134+ sys->werrstr(sprint("bad magic (%x, want %x)", magic, Direntrymagic));
275135 return nil;
276136 }
277137 (de.version, i) = eg16(d, i);
278138 if(de.version != 8 && de.version != 9) {
279− werrstr(sprint("bad version (%d)", de.version));
139+ sys->werrstr(sprint("bad version (%d)", de.version));
280140 return nil;
281141 }
282142 (de.elem, i) = egstring(d, i);
@@ -309,12 +169,28 @@ Direntry.unpack(d: array of byte): ref Direntry · 26 unmodified lines
309169 de.emode |= sys->DMDIR;
310170 if(de.mode&Modetemp)
311171 de.emode |= sys->DMTMP;
312− if(de.version == 9)
313− ; # xxx handle qid space?, can be in here
172+ while(i < len d) {
173+ t := int d[i++];
174+ n: int;
175+ (n, i) = eg16(d, i);
176+ case t {
177+ DirQidspace =>
178+ if(n != 16) {
179+ sys->werrstr(sprint("invalid qidspace length %d", n));
180+ return nil;
181+ }
182+ de.qidspace = 1;
183+ (de.qidoff, i) = eg64(d, i);
184+ (de.qidmax, i) = eg64(d, i);
185+ * =>
186+ # ignore other optional fields
187+ i += n;
188+ }
189+ }
314190 return de;
315191 } exception e {
316192 "too small:*" =>
317− werrstr("direntry "+e);
193+ sys->werrstr("direntry "+e);
318194 return nil;
319195 * =>
320196 raise e;
@@ -340,13 +216,13 @@ Metablock.pack(mb: self ref Metablock, d: array of byte) · 19 unmodified lines
340216 Metablock.unpack(d: array of byte): ref Metablock
341217 {
342218 if(len d < Metablocksize) {
343− werrstr(sprint("bad length for metablock (%d, want %d)", len d, Metablocksize));
219+ sys->werrstr(sprint("bad length for metablock (%d, want %d)", len d, Metablocksize));
344220 return nil;
345221 }
346222 i := 0;
347223 magic := g32(d, i);
348224 if(magic != Metablockmagic && magic != Metablockmagic+1) {
349− werrstr(sprint("bad magic for metablock (%x, need %x)", magic, Metablockmagic));
225+ sys->werrstr(sprint("bad magic for metablock (%x, need %x)", magic, Metablockmagic));
350226 return nil;
351227 }
352228 i += BIT32SZ;
@@ -361,7 +237,7 @@ Metablock.unpack(d: array of byte): ref Metablock · 8 unmodified lines
361237 mb.nindex = g16(d, i);
362238 i += BIT16SZ;
363239 if(mb.nindex == 0) {
364− werrstr("bad metablock, nindex=0");
240+ sys->werrstr("bad metablock, nindex=0");
365241 return nil;
366242 }
367243 return mb;
@@ -378,7 +254,7 @@ Metaentry.unpack(d: array of byte, i: int): ref Metaentry · 10 unmodified lines
378254 {
379255 o := Metablocksize+i*Metaentrysize;
380256 if(o+Metaentrysize > len d) {
381− werrstr(sprint("meta entry lies outside meta block, i=%d", i));
257+ sys->werrstr(sprint("meta entry lies outside meta block, i=%d", i));
382258 return nil;
383259 }
384260
@@ -388,7 +264,7 @@ Metaentry.unpack(d: array of byte, i: int): ref Metaentry · 3 unmodified lines
388264 me.size = g16(d, o);
389265 o += BIT16SZ;
390266 if(me.offset+me.size > len d) {
391− werrstr(sprint("meta entry points outside meta block, i=%d", i));
267+ sys->werrstr(sprint("meta entry points outside meta block, i=%d", i));
392268 return nil;
393269 }
394270 return me;
@@ -435,14 +311,14 @@ fflush(f: ref File, last: int): (int, ref Entry) · 40 unmodified lines
435311 if(!last && !f.p[i].full())
436312 return (0, nil);
437313 if(last && f.p[i].o == Scoresize) {
438− flags := Entryactive;
314+ flags := venti->Entryactive;
439315 if(f.dtype == Dirtype)
440− flags |= Entrydir;
441− flags |= i<<Entrydepthshift;
316+ flags |= venti->Entrydir;
317+ flags |= i<<venti->Entrydepthshift;
442318 score := Score(f.p[i].data());
443319 if(len score.a == 0)
444320 score = Score.zero();
445− return (0, Entry.new(len f.p[i].d, f.dsize, flags, f.size, score));
321+ return (0, ref Entry(0, len f.p[i].d, f.dsize, i, flags, f.size, score));
446322 }
447323 (ok, score) := f.s.write(Pointertype0+i, f.p[i].data());
448324 if(ok < 0)
@@ -456,7 +332,7 @@ fflush(f: ref File, last: int): (int, ref Entry) · 7 unmodified lines
456332 }
457333 f.p[i+1].add(score);
458334 }
459− werrstr("internal error in fflush");
335+ sys->werrstr("internal error in fflush");
460336 return (-1, nil);
461337 }
462338
@@ -601,7 +477,7 @@ MSink.add(m: self ref MSink, de: ref Direntry): int · 138 unmodified lines
601477 d := de.pack();
602478 if(d == nil)
603479 return -1;
604−say(sprint("msink: adding direntry, length %d", len d));
480+if(dflag) say(sprint("msink: adding direntry, length %d", len d));
605481 if(Metablocksize+len m.l*Metaentrysize+m.nde + Metaentrysize+len d > len m.de)
606482 if(mflush(m, 0) < 0)
607483 return -1;
@@ -621,7 +497,7 @@ MSink.finish(m: self ref MSink): ref Entry · 13 unmodified lines
621497 Source.new(s: ref Session, e: ref Entry): ref Source
622498 {
623499 dsize := e.dsize;
624− if(e.flags&Entrydir)
500+ if(e.flags&venti->Entrydir)
625501 dsize = Entrysize*(dsize/Entrysize);
626502 return ref Source(s, e, dsize);
627503 }
@@ -660,7 +536,7 @@ Source.get(s: self ref Source, i: big, d: array of byte): int · 32 unmodified lines
660536 dtype := Pointertype0+depth-1;
661537 if(depth == 0) {
662538 dtype = Datatype;
663− if(s.e.flags & Entrydir)
539+ if(s.e.flags & venti->Entrydir)
664540 dtype = Dirtype;
665541 bsize = want;
666542 }
@@ -714,11 +590,11 @@ Vacfile.read(v: self ref Vacfile, d: array of byte, n: int): int · 47 unmodified lines
714590 Vacfile.pread(v: self ref Vacfile, d: array of byte, n: int, offset: big): int
715591 {
716592 dsize := v.s.dsize;
717−say(sprint("vf.preadn, len d %d, n %d, offset %bd", len d, n, offset));
593+if(dflag) say(sprint("vf.preadn, len d %d, n %d, offset %bd", len d, n, offset));
718594 have := v.s.get(big (offset/big dsize), buf := array[dsize] of byte);
719595 if(have <= 0)
720596 return have;
721−say(sprint("vacfile.pread: have=%d dsize=%d", have, dsize));
597+if(dflag) say(sprint("vacfile.pread: have=%d dsize=%d", have, dsize));
722598 o := int (offset % big dsize);
723599 have -= o;
724600 if(have > n)
@@ -752,7 +628,7 @@ mecmp(d: array of byte, i: int, elem: string, fromfossil: int): (int, int) · 27 unmodified lines
752628 n := g16(d, o);
753629 o += BIT16SZ;
754630 if(o+n > len d) {
755− werrstr("bad elem in direntry");
631+ sys->werrstr("bad elem in direntry");
756632 return (0, 1);
757633 }
758634 return (elemcmp(d[o:o+n], array of byte elem, fromfossil), 0);
@@ -801,54 +677,56 @@ Vacdir.walk(v: self ref Vacdir, elem: string): ref Direntry · 42 unmodified lines
801677 return de;
802678 i++;
803679 }
804− werrstr(sprint("no such file or directory"));
680+ sys->werrstr(sprint("no such file or directory"));
805681 return nil;
806682 }
807683
808684 vfreadentry(vf: ref Vacfile, entry: int): ref Entry
809685 {
810−say(sprint("vfreadentry: reading entry=%d", entry));
686+if(dflag) say(sprint("vfreadentry: reading entry=%d", entry));
811687 ebuf := array[Entrysize] of byte;
812688 n := vf.pread(ebuf, len ebuf, big entry*big Entrysize);
813689 if(n < 0)
814690 return nil;
815691 if(n != len ebuf) {
816− werrstr(sprint("bad archive, entry=%d not present (read %d, wanted %d)", entry, n, len ebuf));
692+ sys->werrstr(sprint("bad archive, entry=%d not present (read %d, wanted %d)", entry, n, len ebuf));
817693 return nil;
818694 }
819695 e := Entry.unpack(ebuf);
820− if(~e.flags&Entryactive) {
821− werrstr("entry not active");
696+ if(e == nil)
697+ return nil;
698+ if(~e.flags&venti->Entryactive) {
699+ sys->werrstr("entry not active");
822700 return nil;
823701 }
824702 # p9p writes archives with Entrylocal set?
825− if(0 && e.flags&Entrylocal) {
826− werrstr("entry is local");
703+ if(0 && e.flags&venti->Entrylocal) {
704+ sys->werrstr("entry is local");
827705 return nil;
828706 }
829−say(sprint("vreadentry: have entry, score=%s", e.score.text()));
707+if(dflag) say(sprint("vreadentry: have entry, score=%s", e.score.text()));
830708 return e;
831709 }
832710
833711 Vacdir.open(vd: self ref Vacdir, de: ref Direntry): (ref Entry, ref Entry)
834712 {
835−say(sprint("vacdir.open: opening entry=%d", de.entry));
713+if(dflag) say(sprint("vacdir.open: opening entry=%d", de.entry));
836714 e := vfreadentry(vd.vf, de.entry);
837715 if(e == nil)
838716 return (nil, nil);
839717 isdir1 := de.mode & Modedir;
840− isdir2 := e.flags & Entrydir;
718+ isdir2 := e.flags & venti->Entrydir;
841719 if(isdir1 && !isdir2 || !isdir1 && isdir2) {
842− werrstr("direntry directory bit does not match entry directory bit");
720+ sys->werrstr("direntry directory bit does not match entry directory bit");
843721 return (nil, nil);
844722 }
845−say(sprint("vacdir.open: have entry, score=%s size=%bd", e.score.text(), e.size));
723+if(dflag) say(sprint("vacdir.open: have entry, score=%s size=%bd", e.score.text(), e.size));
846724 me: ref Entry;
847725 if(de.mode&Modedir) {
848726 me = vfreadentry(vd.vf, de.mentry);
849727 if(me == nil)
850728 return (nil, nil);
851−say(sprint("vacdir.open: have mentry, score=%s size=%bd", me.score.text(), e.size));
729+if(dflag) say(sprint("vacdir.open: have mentry, score=%s size=%bd", me.score.text(), e.size));
852730 }
853731 return (e, me);
854732 }
@@ -860,8 +738,10 @@ readdirentry(buf: array of byte, i: int, allowroot: int): ref Direntry · 5 unmodified lines
860738 return nil;
861739 o := me.offset;
862740 de := Direntry.unpack(buf[o:o+me.size]);
741+ if(de == nil)
742+ return nil;
863743 if(badelem(de.elem) && !(allowroot && de.elem == "/")) {
864− werrstr(sprint("bad direntry: %s", de.elem));
744+ sys->werrstr(sprint("bad direntry: %s", de.elem));
865745 return nil;
866746 }
867747 return de;
@@ -882,12 +762,12 @@ badelem(elem: string): int · 14 unmodified lines
882762
883763 vdreaddir(vd: ref Vacdir, allowroot: int): (int, ref Direntry)
884764 {
885−say(sprint("vdreaddir: ms.e.size=%bd vd.p=%bd vd.i=%d", vd.ms.e.size, vd.p, vd.i));
765+if(dflag) say(sprint("vdreaddir: ms.e.size=%bd vd.p=%bd vd.i=%d", vd.ms.e.size, vd.p, vd.i));
886766 dsize := vd.ms.dsize;
887767 n := vd.ms.get(vd.p, buf := array[dsize] of byte);
888768 if(n <= 0)
889769 return (n, nil);
890−say(sprint("vdreaddir: have buf, length=%d e.size=%bd", n, vd.ms.e.size));
770+if(dflag) say(sprint("vdreaddir: have buf, length=%d e.size=%bd", n, vd.ms.e.size));
891771 mb := Metablock.unpack(buf);
892772 if(mb == nil)
893773 return (-1, nil);
@@ -899,7 +779,7 @@ say(sprint("vdreaddir: have buf, length=%d e.size=%bd", n, vd.ms.e.size)); · 5 unmodified lines
899779 vd.p++;
900780 vd.i = 0;
901781 }
902−say("vdreaddir: have entry");
782+if(dflag) say("vdreaddir: have entry");
903783 return (1, de);
904784 }
905785
@@ -918,20 +798,18 @@ Vacdir.rewind(vd: self ref Vacdir) · 12 unmodified lines
918798
919799 vdroot(session: ref Session, score: Venti->Score): (ref Vacdir, ref Direntry, string)
920800 {
921− d := session.read(score, Roottype, Rootsize);
801+ d := session.read(score, venti->Roottype, venti->Rootsize);
922802 if(d == nil)
923803 return (nil, nil, sprint("reading vac score: %r"));
924804 r := Root.unpack(d);
925805 if(r == nil)
926806 return (nil, nil, sprint("bad vac root block: %r"));
927− say("have root");
928807 topscore := r.score;
929808
930809 d = session.read(topscore, Dirtype, 3*Entrysize);
931810 if(d == nil)
932811 return (nil, nil, sprint("reading rootdir score: %r"));
933812 if(len d != 3*Entrysize) {
934− say("top entries not in directory of 3 elements, assuming it's from fossil");
935813 if(len d % Entrysize != 0 && len d == 2*Entrysize != 0) # what's in the second 40 bytes? looks like 2nd 20 bytes of it is zero score
936814 return (nil, nil, sprint("bad fossil rootdir, have %d bytes, need %d or %d", len d, Entrysize, 2*Entrysize));
937815 e := Entry.unpack(d[:Entrysize]);
@@ -941,9 +819,7 @@ vdroot(session: ref Session, score: Venti->Score): (ref Vacdir, ref Direntry, st · 3 unmodified lines
941819 d = session.read(topscore, Dirtype, 3*Entrysize);
942820 if(d == nil)
943821 return (nil, nil, sprint("reading fossil rootdir block: %r"));
944− say("have fossil top entries");
945822 }
946− say("have top entries");
947823
948824 e := array[3] of ref Entry;
949825 j := 0;
@@ -953,14 +829,13 @@ vdroot(session: ref Session, score: Venti->Score): (ref Vacdir, ref Direntry, st · 3 unmodified lines
953829 return (nil, nil, sprint("reading root entry %d: %r", j));
954830 j++;
955831 }
956− say("top entries unpacked");
832+if(dflag) say("top entries unpacked");
957833
958834 mroot := Vacdir.mk(nil, Source.new(session, e[2]));
959835 (ok, de) := vdreaddir(mroot, 1);
960836 if(ok <= 0)
961837 return (nil, nil, sprint("reading root meta entry: %r"));
962838
963−say(sprint("vdroot: new score=%s", score.text()));
964839 return (Vacdir.new(session, e[0], e[1]), de, nil);
965840 }
966841
@@ -974,6 +849,32 @@ checksize(n: int): int · 7 unmodified lines
974849 return 1;
975850 }
976851
852+
853+gstring(a: array of byte, o: int): (string, int)
854+{
855+ if(o < 0 || o+BIT16SZ > len a)
856+ return (nil, -1);
857+ l := (int a[o] << 8) | int a[o+1];
858+ if(l > Maxstringsize)
859+ return (nil, -1);
860+ o += BIT16SZ;
861+ e := o+l;
862+ if(e > len a)
863+ return (nil, -1);
864+ return (string a[o:e], e);
865+}
866+
867+gtstring(a: array of byte, o: int, n: int): string
868+{
869+ e := o + n;
870+ if(e > len a)
871+ return nil;
872+ for(i := o; i < e; i++)
873+ if(a[i] == byte 0)
874+ break;
875+ return string a[o:i];
876+}
877+
977878 gscore(f: array of byte, i: int): Score
978879 {
979880 s := Score(array[Scoresize] of byte);
@@ -993,16 +894,12 @@ g32(f: array of byte, i: int): int · 13 unmodified lines
993894
994895 g48(f: array of byte, i: int): big
995896 {
996− b1 := (((((int f[i+0] << 8) | int f[i+1]) << 8) | int f[i+2]) << 8) | int f[i+3];
997− b0 := (int f[i+4] << 8) | int f[i+5];
998− return (big b1 << 16) | big b0;
897+ return big g16(f, i)<<32 | (big g32(f, i+2) & 16rFFFFFFFF);
999898 }
1000899
1001900 g64(f: array of byte, i: int): big
1002901 {
1003− b0 := (((((int f[i+3] << 8) | int f[i+2]) << 8) | int f[i+1]) << 8) | int f[i];
1004− b1 := (((((int f[i+7] << 8) | int f[i+6]) << 8) | int f[i+5]) << 8) | int f[i+4];
1005− return (big b1 << 32) | (big b0 & 16rFFFFFFFF);
902+ return big g32(f, i)<<32 | (big g32(f, i+4) & 16rFFFFFFFF);
1006903 }
1007904
1008905 p16(d: array of byte, i: int, v: int): int
@@ -1033,6 +930,16 @@ p64(d: array of byte, i: int, v: big): int · 24 unmodified lines
1033930 return i+BIT64SZ;
1034931 }
1035932
933+pstring(a: array of byte, o: int, s: string): int
934+{
935+ sa := array of byte s; # could do conversion ourselves
936+ n := len sa;
937+ a[o] = byte (n >> 8);
938+ a[o+1] = byte n;
939+ a[o+2:] = sa;
940+ return o+BIT16SZ+n;
941+}
942+
1036943 ptstring(d: array of byte, i: int, s: string, l: int): int
1037944 {
1038945 a := array of byte s;
@@ -1101,5 +1008,5 @@ eg64(f: array of byte, i: int): (big, int) · 62 unmodified lines
11011008 say(s: string)
11021009 {
11031010 if(dflag)
1104− fprint(fildes(2), "%s\n", s);
1011+ sys->fprint(sys->fildes(2), "%s\n", s);
11051012 }
appl/lib/venti.b+97−4
@@ -2,6 +2,7 @@ implement Venti; · 1 unmodified line
22
33 include "sys.m";
44 sys: Sys;
5+ sprint: import sys;
56 include "venti.m";
67
78 BIT8SZ: con 1;
@@ -566,7 +567,34 @@ gtstring(a: array of byte, o: int, n: int): string · 558 unmodified lines
566567 break;
567568 return string a[o:i];
568569 }
569−unpackroot(d: array of byte): ref Root
570+
571+Root.pack(r: self ref Root): array of byte
572+{
573+ d := array[Rootsize] of byte;
574+ i := 0;
575+ i = p16(d, i, r.version);
576+ i = ptstring(d, i, r.name, Rootnamelen);
577+ if(i < 0)
578+ return nil;
579+ i = ptstring(d, i, r.rtype, Rootnamelen);
580+ if(i < 0)
581+ return nil;
582+ i = pscore(d, i, r.score);
583+ i = p16(d, i, r.blocksize);
584+ if(r.prev == nil) {
585+ for(j := 0; j < Scoresize; j++)
586+ d[i+j] = byte 0;
587+ i += Scoresize;
588+ } else
589+ i = pscore(d, i, *r.prev);
590+ if(i != len d) {
591+ sys->werrstr("root pack, bad length: "+string i);
592+ return nil;
593+ }
594+ return d;
595+}
596+
597+Root.unpack(d: array of byte): ref Root
570598 {
571599 if(len d != Rootsize){
572600 sys->werrstr("root entry is wrong length");
@@ -587,11 +615,34 @@ unpackroot(d: array of byte): ref Root · 14 unmodified lines
587615 o += Scoresize;
588616 r.blocksize = g16(d, o);
589617 o += BIT16SZ;
590− r.prev = gscore(d, o);
618+ prev := gscore(d, o);
619+ if(!prev.eq(Score(array[Scoresize] of {* => byte 0})))
620+ r.prev = ref prev;
591621 return r;
592622 }
593623
594−unpackentry(d: array of byte): ref Entry
624+
625+Entry.pack(e: self ref Entry): array of byte
626+{
627+ d := array[Entrysize] of byte;
628+ i := 0;
629+ i = p32(d, i, e.gen);
630+ i = p16(d, i, e.psize);
631+ i = p16(d, i, e.dsize);
632+ e.flags |= e.depth<<Entrydepthshift;
633+ d[i++] = byte e.flags;
634+ for(j := 0; j < 5; j++)
635+ d[i++] = byte 0;
636+ i = p48(d, i, e.size);
637+ i = pscore(d, i, e.score);
638+ if(i != len d) {
639+ sys->werrstr(sprint("bad length, have %d, want %d", i, len d));
640+ return nil;
641+ }
642+ return d;
643+}
644+
645+Entry.unpack(d: array of byte): ref Entry
595646 {
596647 if(len d != Entrysize){
597648 sys->werrstr("entry is wrong length");
@@ -606,7 +657,7 @@ unpackentry(d: array of byte): ref Entry · 8 unmodified lines
606657 e.dsize = g16(d, i);
607658 i += BIT16SZ;
608659 e.flags = int d[i];
609− e.depth= (e.flags & Entrydepthmask) >> Entrydepthshift;
660+ e.depth = (e.flags & Entrydepthmask) >> Entrydepthshift;
610661 e.flags &= ~Entrydepthmask;
611662 i += BIT8SZ;
612663 i += 5; # skip something...
@@ -662,3 +713,45 @@ g64(f: array of byte, i: int): big · 49 unmodified lines
662713 b1 := (((((int f[i+4] << 8) | int f[i+5]) << 8) | int f[i+6]) << 8) | int f[i+7];
663714 return (big b0 << 32) | (big b1 & 16rFFFFFFFF);
664715 }
716+
717+p16(d: array of byte, i: int, v: int): int
718+{
719+ d[i+0] = byte (v>>8);
720+ d[i+1] = byte v;
721+ return i+BIT16SZ;
722+}
723+
724+p32(d: array of byte, i: int, v: int): int
725+{
726+ p16(d, i+0, v>>16);
727+ p16(d, i+2, v);
728+ return i+BIT32SZ;
729+}
730+
731+p48(d: array of byte, i: int, v: big): int
732+{
733+ p16(d, i+0, int (v>>32));
734+ p32(d, i+2, int v);
735+ return i+BIT48SZ;
736+}
737+
738+ptstring(d: array of byte, i: int, s: string, l: int): int
739+{
740+ a := array of byte s;
741+ if(len a > l) {
742+ sys->werrstr("string too long: "+s);
743+ return -1;
744+ }
745+ for(j := 0; j < len a; j++)
746+ d[i+j] = a[j];
747+ while(j < l)
748+ d[i+j++] = byte 0;
749+ return i+l;
750+}
751+
752+pscore(d: array of byte, i: int, s: Score): int
753+{
754+ for(j := 0; j < Scoresize; j++)
755+ d[i+j] = s.a[j];
756+ return i+Scoresize;
757+}
dis/lib/vac.dis+0−0

Binary file not shown.

dis/lib/venti.dis+0−0

Binary file not shown.

dis/vacfs.dis+0−0

Binary file not shown.

dis/vacget.dis+0−0

Binary file not shown.

dis/vacput.dis+0−0

Binary file not shown.

include/version.h+1−1
@@ -1 +1 @@
1−#define VERSION "Fourth Edition (20110426)"
1+#define VERSION "Fourth Edition (20110516)"
man/1/vacget+31−3
@@ -15,6 +15,10 @@ vacget, vacput \- venti archive utilities · 14 unmodified lines
1515 [
1616 .B -vd
1717 ] [
18+.B -i
19+|
20+.B -x
21+] [
1822 .B -a
1923 .I addr
2024 ] [
@@ -23,6 +27,10 @@ vacget, vacput \- venti archive utilities · 2 unmodified lines
2327 ] [
2428 .B -n
2529 .I name
30+] [
31+.B -u uid
32+] [
33+.B -g gid
2634 ]
2735 .I path ...
2836 .SH DESCRIPTION
@@ -62,14 +70,34 @@ bytes instead of the default 8192 byte blocks. Only for vacput. · 33 unmodified lines
6270 Use
6371 .I name
6472 as the name in the root block. Only for vacput.
73+.TP
74+.BR -i " or " -x
75+Read a list of files from stdin to include
76+.RB ( -i )
77+or exclude
78+.RB ( -x )
79+from the (recursively walked)
80+.I paths
81+specified on the command-line.
82+Only for vacput.
83+.TP
84+.BI -u " uid"
85+Use
86+.I uid
87+for all files.
88+Only for vacput.
89+.TP
90+.BI -g " gid"
91+Use
92+.I gid
93+for all files.
94+Only for vacput.
6595 .SH SOURCE
6696 .B /appl/cmd/vacget.b
6797 .br
6898 .B /appl/cmd/vacput.b
6999 .SH SEE ALSO
70−.IR vcache (1),
71100 .IR venti (2),
72−.IR vacfs (4),
73−.IR ventisrv (8)
101+.IR vacfs (4)
74102 .SH BUGS
75103 These tools need more testing.
man/2/venti+3−7
@@ -8,8 +8,6 @@ venti := load Venti Venti->PATH; · 7 unmodified lines
88 Session: import venti;
99
1010 init: fn();
11−unpackentry: fn(d: array of byte): ref Entry;
12−unpackroot: fn(d: array of byte): ref Root;
1311
1412 Session: adt {
1513 new: fn(fd: ref Sys->FD): ref Session;
@@ -48,7 +46,7 @@ Blocks are additionally tagged with a · 32 unmodified lines
4846 facilitating recovery in the event of corruption.
4947 A
5048 .B Session
51−represents an session with a Venti server.
49+represents a session with a Venti server.
5250 .TP
5351 .IB s .new(\fIfd\fP)
5452 .B New
@@ -99,9 +97,7 @@ contains the Venti score for the block that has been written. · 44 unmodified lines
9997 tells the Venti server to make sure that all data is committed to
10098 active storage.
10199 .SH SOURCE
100+.B /module/venti.m
101+.br
102102 .B /appl/lib/venti.b
103103 .SH BUGS
104−to do:
105−Score adt
106−entry packing/unpacking
107−other Vmsgs, Session.rpc()?
module/vac.m+17−46
@@ -4,9 +4,6 @@ Vac: module { · 3 unmodified lines
44
55 dflag: int;
66
7− # taken from venti.m, merge back later
8− # some of this needs to be removed from venti.m since it does not belong there
9−
107 # mode bits
118 Modeperm: con 8r777;
129 Modesticky,
@@ -24,45 +21,16 @@ Vac: module { · 11 unmodified lines
2421 Modedev,
2522 Modenamedpipe: con 1<<(9+iota);
2623
27− Entrysize: con 40;
28− Rootsize: con 300;
2924 Metablocksize: con 12;
3025 Metaentrysize: con 4;
3126
3227 Dsize: con 8*1024;
3328
34− Entryactive: con (1<<0); # entry is in use
35− Entrydir: con (1<<1); # a directory
36− Entrydepthshift: con 2; # shift for pointer depth
37− Entrydepthmask: con (16r7<<2); # mask for pointer depth
38− Entrylocal: con (1<<5); # used for local storage: should not be set for venti blocks
39−
40− Root: adt {
41− version: int;
42− name: string;
43− rtype: string;
44− score: Venti->Score; # to a Dir block
45− blocksize: int; # maximum block size
46− prev: ref Venti->Score; # last root block
47−
48− new: fn(name, rtype: string, score: Venti->Score, blocksize: int, prev: ref Venti->Score): ref Root;
49− unpack: fn(d: array of byte): ref Root;
50− pack: fn(r: self ref Root): array of byte;
51− };
52−
53− Entry: adt {
54− gen: int; # generation number (XXX should be unsigned)
55− psize: int; # pointer block size
56− dsize: int; # data block size
57− depth: int; # unpacked from flags
58− flags: int;
59− size: big; # (XXX should be unsigned)
60− score: Venti->Score;
61−
62− new: fn(psize, dsize, flags: int, size: big, score: Venti->Score): ref Entry;
63− pack: fn(e: self ref Entry): array of byte;
64− unpack: fn(d: array of byte): ref Entry;
65− };
29+ # DirPlan9, DirNT & DirGen not valid in version >= 9
30+ DirPlan9,
31+ DirNT,
32+ DirQidspace,
33+ DirGen: con 1+iota;
6634
6735 Direntry: adt {
6836 version: int;
@@ -72,6 +40,9 @@ Vac: module { · 3 unmodified lines
7240 qid: big;
7341 uid, gid, mid: string;
7442 mtime, mcount, ctime, atime, mode, emode: int;
43+ qidspace: int;
44+ qidoff: big;
45+ qidmax: big;
7546
7647 new: fn(): ref Direntry;
7748 mk: fn(d: Sys->Dir): ref Direntry;
@@ -115,7 +86,7 @@ Vac: module { · 37 unmodified lines
11586
11687 new: fn(s: ref Venti->Session, dtype, dsize: int): ref File;
11788 write: fn(f: self ref File, d: array of byte): int;
118− finish: fn(f: self ref File): ref Entry;
89+ finish: fn(f: self ref File): ref Venti->Entry;
11990 };
12091
12192 # for writing venti directories
@@ -125,8 +96,8 @@ Vac: module { · 3 unmodified lines
12596 nd, ne: int;
12697
12798 new: fn(s: ref Venti->Session, dsize: int): ref Sink;
128− add: fn(m: self ref Sink, e: ref Entry): int;
129− finish: fn(m: self ref Sink): ref Entry;
99+ add: fn(m: self ref Sink, e: ref Venti->Entry): int;
100+ finish: fn(m: self ref Sink): ref Venti->Entry;
130101 };
131102
132103 Mentry: adt {
@@ -145,16 +116,16 @@ Vac: module { · 12 unmodified lines
145116
146117 new: fn(s: ref Venti->Session, dsize: int): ref MSink;
147118 add: fn(m: self ref MSink, de: ref Direntry): int;
148− finish: fn(m: self ref MSink): ref Entry;
119+ finish: fn(m: self ref MSink): ref Venti->Entry;
149120 };
150121
151122 # for reading pages from a hash tree referenced by an entry
152123 Source: adt {
153124 session: ref Venti->Session;
154− e: ref Entry;
125+ e: ref Venti->Entry;
155126 dsize: int; # real dsize
156127
157− new: fn(s: ref Venti->Session, e: ref Entry): ref Source;
128+ new: fn(s: ref Venti->Session, e: ref Venti->Entry): ref Source;
158129 get: fn(s: self ref Source, i: big, d: array of byte): int;
159130 };
160131
@@ -164,7 +135,7 @@ Vac: module { · 3 unmodified lines
164135 o: big;
165136
166137 mk: fn(s: ref Source): ref Vacfile;
167− new: fn(session: ref Venti->Session, e: ref Entry): ref Vacfile;
138+ new: fn(session: ref Venti->Session, e: ref Venti->Entry): ref Vacfile;
168139 read: fn(v: self ref Vacfile, d: array of byte, n: int): int;
169140 seek: fn(v: self ref Vacfile, offset: big): big;
170141 pread: fn(v: self ref Vacfile, d: array of byte, n: int, offset: big): int;
@@ -178,9 +149,9 @@ Vac: module { · 7 unmodified lines
178149 i: int;
179150
180151 mk: fn(vf: ref Vacfile, ms: ref Source): ref Vacdir;
181− new: fn(session: ref Venti->Session, e, me: ref Entry): ref Vacdir;
152+ new: fn(session: ref Venti->Session, e, me: ref Venti->Entry): ref Vacdir;
182153 walk: fn(v: self ref Vacdir, elem: string): ref Direntry;
183− open: fn(v: self ref Vacdir, de: ref Direntry): (ref Entry, ref Entry);
154+ open: fn(v: self ref Vacdir, de: ref Direntry): (ref Venti->Entry, ref Venti->Entry);
184155 readdir: fn(v: self ref Vacdir): (int, ref Direntry);
185156 rewind: fn(v: self ref Vacdir);
186157 };
module/venti.m+7−3
@@ -124,7 +124,10 @@ Venti: module { · 123 unmodified lines
124124 rtype: string;
125125 score: Venti->Score; # to a Dir block
126126 blocksize: int; # maximum block size
127− prev: Venti->Score; # last root block
127+ prev: ref Venti->Score; # last root block
128+
129+ pack: fn(r: self ref Root): array of byte;
130+ unpack: fn(d: array of byte): ref Root;
128131 };
129132
130133 Entry: adt {
@@ -135,6 +138,9 @@ Venti: module { · 4 unmodified lines
135138 flags: int;
136139 size: big; # (XXX should be unsigned)
137140 score: Venti->Score;
141+
142+ pack: fn(e: self ref Entry): array of byte;
143+ unpack: fn(d: array of byte): ref Entry;
138144 };
139145 Score: adt {
140146 a: array of byte;
@@ -153,7 +159,5 @@ Venti: module { · 12 unmodified lines
153159 sync: fn(s: self ref Session): int;
154160 rpc: fn(s: self ref Session, m: ref Vmsg): (ref Vmsg, string);
155161 };
156− unpackentry: fn(d: array of byte): ref Entry;
157− unpackroot: fn(d: array of byte): ref Root;
158162 init: fn();
159163 };
opt/README+1−0
@@ -1 +1,2 @@
11 optional components live in subdirectories of /opt.
2+see opt(6) and opt(1)