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 @@
120110516
2 merge changes from vac branch of mechiel-inferno-os (googlecode)
120110426320110426
2 emu/Linux/asm-arm.S linux system call interface changed [issue 215, mechiel]4 emu/Linux/asm-arm.S linux system call interface changed [issue 215, mechiel]
320110419520110419
appl/cmd/vacfs.b+62−50
@@ -2,35 +2,36 @@ implement Vacfs; · 1 unmodified line
2 2
3include "sys.m";3include "sys.m";
4 sys: Sys;4 sys: Sys;
5 sprint: import sys;
5include "draw.m";6include "draw.m";
6include "arg.m";7include "arg.m";
8include "dial.m";
9 dial: Dial;
7include "string.m";10include "string.m";
11 str: String;
8include "daytime.m";12include "daytime.m";
13 dt: Daytime;
9include "venti.m";14include "venti.m";
15 venti: Venti;
16 Root, Entry, Score, Session: import venti;
17 Roottype, Dirtype, Pointertype0, Datatype: import venti;
10include "vac.m";18include "vac.m";
19 vac: Vac;
20 Direntry, Vacdir, Vacfile: import vac;
11include "styx.m";21include "styx.m";
12 styx: Styx;22 styx: Styx;
13 Tmsg, Rmsg: import styx;23 Tmsg, Rmsg: import styx;
14include "styxservers.m";24include "styxservers.m";
15 25 styxservers: Styxservers;
16str: String;26 Styxserver, Fid, Navigator, Navop, Enotfound: import styxservers;
17daytime: Daytime;
18venti: Venti;
19vac: Vac;
20styxservers: Styxservers;
21
22print, sprint, fprint, fildes: import sys;
23Score, Session: import venti;
24Roottype, Dirtype, Pointertype0, Datatype: import venti;
25Root, Entry, Direntry, Metablock, Metaentry, Entrysize, Modeperm, Modeappend, Modeexcl, Modedir, Modesnapshot, Vacdir, Vacfile, Source: import vac;
26Styxserver, Fid, Navigator, Navop, Enotfound: import styxservers;
27 27
28Vacfs: module {28Vacfs: module {
29 init: fn(nil: ref Draw->Context, args: list of string);29 init: fn(nil: ref Draw->Context, args: list of string);
30};30};
31 31
32addr := "net!$venti!venti";32addr := "$venti";
33dflag := pflag := 0;33dflag: int;
34pflag: int;
34session: ref Session;35session: ref Session;
35 36
36ss: ref Styxserver;37ss: ref Styxserver;
@@ -183,7 +184,7 @@ getfile(qid: int): ref Elem.File · 146 unmodified lines
183 pick file := get(qid) {184 pick file := get(qid) {
184 File => return file;185 File => return file;
185 }186 }
186 error("internal error, getfile");187 fail("internal error, getfile");
187 return nil;188 return nil;
188}189}
189 190
@@ -192,7 +193,7 @@ getdir(qid: int): ref Elem.Dir · 2 unmodified lines
192 pick d := get(qid) {193 pick d := get(qid) {
193 Dir => return d;194 Dir => return d;
194 }195 }
195 error("internal error, getdir");196 fail("internal error, getdir");
196 return nil;197 return nil;
197}198}
198 199
@@ -200,8 +201,9 @@ init(nil: ref Draw->Context, args: list of string) · 1 unmodified line
200{201{
201 sys = load Sys Sys->PATH;202 sys = load Sys Sys->PATH;
202 arg := load Arg Arg->PATH;203 arg := load Arg Arg->PATH;
204 dial = load Dial Dial->PATH;
203 str = load String String->PATH;205 str = load String String->PATH;
204 daytime = load Daytime Daytime->PATH;206 dt = load Daytime Daytime->PATH;
205 venti = load Venti Venti->PATH;207 venti = load Venti Venti->PATH;
206 styx = load Styx Styx->PATH;208 styx = load Styx Styx->PATH;
207 styxservers = load Styxservers Styxservers->PATH;209 styxservers = load Styxservers Styxservers->PATH;
@@ -213,7 +215,7 @@ init(nil: ref Draw->Context, args: list of string) · 5 unmodified lines
213 215
214 sys->pctl(sys->NEWPGRP, nil);216 sys->pctl(sys->NEWPGRP, nil);
215 if(venti == nil || vac == nil)217 if(venti == nil || vac == nil)
216 error("loading venti,vac");218 fail("loading venti,vac");
217 219
218 arg->init(args);220 arg->init(args);
219 arg->setusage(arg->progname()+" [-Ddp] [-a addr] [[tag:]score]");221 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
221 case ch {223 case ch {
222 'D' => styxservers->traceset(1);224 'D' => styxservers->traceset(1);
223 'a' => addr = arg->earg();225 'a' => addr = arg->earg();
224 'd' => dflag++;226 'd' => vac->dflag = dflag++;
225 vac->dflag++;
226 'p' => pflag++;227 'p' => pflag++;
227 * => warn(sprint("bad option: -%c", ch));228 * => arg->usage();
228 arg->usage();
229 }229 }
230 args = arg->argv();230 args = arg->argv();
231 if(len args > 1)231 if(len args > 1)
@@ -239,22 +239,23 @@ init(nil: ref Draw->Context, args: list of string) · 7 unmodified lines
239 if(tag == nil)239 if(tag == nil)
240 tag = "vac";240 tag = "vac";
241 if(tag != "vac")241 if(tag != "vac")
242 error("bad score type: "+tag);242 fail("bad score type: "+tag);
243 (ok, s) := Score.parse(scorestr);243 (ok, s) := Score.parse(scorestr);
244 if(ok != 0)244 if(ok != 0)
245 error("bad score: "+scorestr);245 fail("bad score: "+scorestr);
246 score = ref s;246 score = ref s;
247 }247 }
248 248
249 (cok, conn) := sys->dial(addr, nil);249 addr = dial->netmkaddr(addr, "net", "venti");
250 if(cok < 0)250 cc := dial->dial(addr, nil);
251 error(sprint("dialing %s: %r", addr));251 if(cc == nil)
252 fail(sprint("dialing %s: %r", addr));
252 say("have connection");253 say("have connection");
253 254
254 fd := conn.dfd;255 fd := cc.dfd;
255 session = Session.new(fd);256 session = Session.new(fd);
256 if(session == nil)257 if(session == nil)
257 error(sprint("handshake: %r"));258 fail(sprint("handshake: %r"));
258 say("have handshake");259 say("have handshake");
259 260
260 rqid := 0;261 rqid := 0;
@@ -262,14 +263,14 @@ init(nil: ref Draw->Context, args: list of string) · 1 unmodified line
262 if(args == nil) {263 if(args == nil) {
263 de := Direntry.new();264 de := Direntry.new();
264 de.uid = de.gid = de.mid = user();265 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();
266 de.mode = Vac->Modedir|8r755;267 de.mode = Vac->Modedir|8r755;
267 de.emode = Sys->DMDIR|8r755;268 de.emode = Sys->DMDIR|8r755;
268 red = ref Elem.Dir(rqid, de, big 0, nil, rqid, 0, 0, nil);269 red = ref Elem.Dir(rqid, de, big 0, nil, rqid, 0, 0, nil);
269 } else {270 } else {
270 (vd, de, err) := vac->vdroot(session, *score);271 (vd, de, err) := vac->vdroot(session, *score);
271 if(err != nil)272 if(err != nil)
272 error(err);273 fail(err);
273 rqid = ++lastqid;274 rqid = ++lastqid;
274 red = ref Elem.Dir(rqid, de, big 0, vd, rqid, 0, 0, nil);275 red = ref Elem.Dir(rqid, de, big 0, vd, rqid, 0, 0, nil);
275 }276 }
@@ -284,12 +285,16 @@ init(nil: ref Draw->Context, args: list of string) · 8 unmodified lines
284 (msgc, ss) = Styxserver.new(sys->fildes(0), nav, big rqid);285 (msgc, ss) = Styxserver.new(sys->fildes(0), nav, big rqid);
285 286
286 for(;;) {287 for(;;) {
287 pick m := <- msgc {288 mm := <-msgc;
289 if(mm == nil)
290 fail("eof");
291
292 pick m := mm {
288 Readerror =>293 Readerror =>
289 say("read error: "+m.error);294 fail("read error: "+m.error);
290 295
291 Read =>296 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));
293 (c, err) := ss.canread(m);298 (c, err) := ss.canread(m);
294 if(c == nil){299 if(c == nil){
295 ss.reply(ref Rmsg.Error(m.tag, err));300 ss.reply(ref Rmsg.Error(m.tag, err));
@@ -353,14 +358,14 @@ navigator(c: chan of ref Navop) · 57 unmodified lines
353loop:358loop:
354 for(;;) {359 for(;;) {
355 navop := <- c;360 navop := <- c;
356 say(sprint("have navop, path=%bd", navop.path));361 if(dflag) say(sprint("have navop, path=%bd", navop.path));
357 pick n := navop {362 pick n := navop {
358 Stat =>363 Stat =>
359 say(sprint("have stat"));364 if(dflag) say(sprint("have stat"));
360 n.reply <-= (get(int n.path).stat(), nil);365 n.reply <-= (get(int n.path).stat(), nil);
361 366
362 Walk =>367 Walk =>
363 say(sprint("have walk, name=%q", n.name));368 if(dflag) say(sprint("have walk, name=%q", n.name));
364 ed := getdir(int n.path);369 ed := getdir(int n.path);
365 (ne, err) := walk(ed, n.name);370 (ne, err) := walk(ed, n.name);
366 if(err != nil) {371 if(err != nil) {
@@ -370,7 +375,7 @@ loop: · 3 unmodified lines
370 n.reply <-= (ne.stat(), nil);375 n.reply <-= (ne.stat(), nil);
371 376
372 Readdir =>377 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));
374 if(n.path == big 0) {379 if(n.path == big 0) {
375 n.reply <-= (nil, nil);380 n.reply <-= (nil, nil);
376 break;381 break;
@@ -423,22 +428,21 @@ loop: · 46 unmodified lines
423 428
424user(): string429user(): string
425{430{
426 if((fd := sys->open("/dev/user", Sys->OREAD)) != nil431 fd := sys->open("/dev/user", Sys->OREAD);
427 && (n := sys->read(fd, d := array[128] of byte, len d)) > 0)432 if(fd != nil)
433 if((n := sys->read(fd, d := array[128] of byte, len d)) > 0)
428 return string d[:n];434 return string d[:n];
429 return "nobody";435 return "nobody";
430}436}
431 437
432error(s: string)438pid(): int
433{439{
434 killgrp();440 return sys->pctl(0, nil);
435 fprint(fildes(2), "%s\n", s);
436 raise "fail:"+s;
437}441}
438 442
439warn(s: string)443killgrp(pid: int)
440{444{
441 fprint(fildes(2), "%s\n", s);445 sys->fprint(sys->open(sprint("/prog/%d/ctl", pid), sys->OWRITE), "killgrp");
442}446}
443 447
444say(s: string)448say(s: string)
@@ -447,9 +451,17 @@ say(s: string) · 2 unmodified lines
447 warn(s);451 warn(s);
448}452}
449 453
450killgrp()454fd2: ref Sys->FD;
455warn(s: string)
451{456{
452 fd := sys->open("/prog/"+string sys->pctl(0, nil)+"/ctl", sys->OWRITE);457 if(fd2 == nil)
453 if(fd != nil)458 fd2 = sys->fildes(2);
454 sys->fprint(fd, "killgrp\n");459 sys->fprint(fd2, "%s\n", s);
460}
461
462fail(s: string)
463{
464 warn(s);
465 killgrp(pid());
466 raise "fail:"+s;
455}467}
appl/cmd/vacget.b+48−42
@@ -2,30 +2,33 @@ implement Vacget; · 1 unmodified line
2 2
3include "sys.m";3include "sys.m";
4 sys: Sys;4 sys: Sys;
5 sprint: import sys;
5include "draw.m";6include "draw.m";
6include "bufio.m";7include "bufio.m";
7 bufio: Bufio;8 bufio: Bufio;
8 Iobuf: import bufio;9 Iobuf: import bufio;
9include "arg.m";10include "arg.m";
11include "dial.m";
12 dial: Dial;
10include "string.m";13include "string.m";
14 str: String;
11include "venti.m";15include "venti.m";
16 venti: Venti;
17 Root, Entry, Score, Session: import venti;
12include "vac.m";18include "vac.m";
13 19 vac: Vac;
14str: String;20 Direntry, Vacdir, Vacfile: import vac;
15venti: Venti;
16vac: Vac;
17
18print, sprint, fprint, fildes: import sys;
19Score, Session: import venti;
20Roottype, Dirtype, Pointertype0, Datatype: import venti;
21Root, Entry, Direntry, Metablock, Metaentry, Entrysize, Modeperm, Modeappend, Modeexcl, Modedir, Modesnapshot, Vacdir, Vacfile, Source: import vac;
22 21
23Vacget: module {22Vacget: module {
24 init: fn(nil: ref Draw->Context, args: list of string);23 init: fn(nil: ref Draw->Context, args: list of string);
25};24};
26 25
27addr := "net!$venti!venti";26addr := "$venti";
28dflag := vflag := pflag := tflag := 0;27dflag: int;
28vflag: int;
29pflag: int;
30tflag: int;
31
29session: ref Session;32session: ref Session;
30 33
31init(nil: ref Draw->Context, args: list of string)34init(nil: ref Draw->Context, args: list of string)
@@ -33,26 +36,25 @@ init(nil: ref Draw->Context, args: list of string) · 1 unmodified line
33 sys = load Sys Sys->PATH;36 sys = load Sys Sys->PATH;
34 bufio = load Bufio Bufio->PATH;37 bufio = load Bufio Bufio->PATH;
35 arg := load Arg Arg->PATH;38 arg := load Arg Arg->PATH;
39 dial = load Dial Dial->PATH;
36 str = load String String->PATH;40 str = load String String->PATH;
37 venti = load Venti Venti->PATH;41 venti = load Venti Venti->PATH;
38 vac = load Vac Vac->PATH;42 vac = load Vac Vac->PATH;
39 if(venti == nil || vac == nil)43 if(venti == nil || vac == nil)
40 error("loading venti,vac");44 fail("loading venti,vac");
41 venti->init();45 venti->init();
42 vac->init();46 vac->init();
43 47
44 arg->init(args);48 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");
46 while((c := arg->opt()) != 0)50 while((c := arg->opt()) != 0)
47 case c {51 case c {
48 'a' => addr = arg->earg();52 'a' => addr = arg->earg();
49 'd' => dflag++;53 'd' => vac->dflag = dflag++;
50 vac->dflag++;
51 'p' => pflag++;54 'p' => pflag++;
52 't' => tflag++;55 't' => tflag++;
53 'v' => vflag++;56 'v' => vflag++;
54 * => warn(sprint("bad option: -%c", c));57 * => arg->usage();
55 arg->usage();
56 }58 }
57 args = arg->argv();59 args = arg->argv();
58 if(len args != 1)60 if(len args != 1)
@@ -64,27 +66,28 @@ init(nil: ref Draw->Context, args: list of string) · 5 unmodified lines
64 if(tag == nil)66 if(tag == nil)
65 tag = "vac";67 tag = "vac";
66 if(tag != "vac")68 if(tag != "vac")
67 error("bad score type: "+tag);69 fail("bad score type: "+tag);
68 70
69 (sok, score) := Score.parse(scorestr);71 (sok, score) := Score.parse(scorestr);
70 if(sok != 0)72 if(sok != 0)
71 error("bad score: "+scorestr);73 fail("bad score: "+scorestr);
72 say("have score");74 say("have score");
73 75
74 (cok, conn) := sys->dial(addr, nil);76 addr = dial->netmkaddr(addr, "net", "venti");
75 if(cok < 0)77 cc := dial->dial(addr, nil);
76 error(sprint("dialing %s: %r", addr));78 if(cc == nil)
79 fail(sprint("dialing %s: %r", addr));
77 say("have connection");80 say("have connection");
78 81
79 fd := conn.dfd;82 fd := cc.dfd;
80 session = Session.new(fd);83 session = Session.new(fd);
81 if(session == nil)84 if(session == nil)
82 error(sprint("handshake: %r"));85 fail(sprint("handshake: %r"));
83 say("have handshake");86 say("have handshake");
84 87
85 (vd, nil, err) := vac->vdroot(session, score);88 (vd, nil, err) := vac->vdroot(session, score);
86 if(err != nil)89 if(err != nil)
87 error(err);90 fail(err);
88 91
89 say("starting walk");92 say("starting walk");
90 walk(".", vd);93 walk(".", vd);
@@ -120,21 +123,21 @@ walk(path: string, vd: ref Vacdir) · 29 unmodified lines
120 for(;;) {123 for(;;) {
121 (n, de) := vd.readdir();124 (n, de) := vd.readdir();
122 if(n < 0)125 if(n < 0)
123 error(sprint("reading direntry in %s: %r", path));126 fail(sprint("reading direntry in %s: %r", path));
124 if(n == 0)127 if(n == 0)
125 break;128 break;
126 say("walk: have direntry, elem="+de.elem);129 if(dflag) say("walk: have direntry, elem="+de.elem);
127 newpath := path+"/"+de.elem;130 newpath := path+"/"+de.elem;
128 (e, me) := vd.open(de);131 (e, me) := vd.open(de);
129 if(e == nil)132 if(e == nil)
130 error(sprint("reading entry for %s: %r", newpath));133 fail(sprint("reading entry for %s: %r", newpath));
131 134
132 oflags := de.mode&~(Modeperm|Modeappend|Modeexcl|Modedir|Modesnapshot);135 oflags := de.mode&~(vac->Modeperm|vac->Modeappend|vac->Modeexcl|vac->Modedir|vac->Modesnapshot);
133 if(oflags)136 if(oflags)
134 warn(sprint("%s: not all bits in mode can be set: 0x%x", newpath, oflags));137 warn(sprint("%s: not all bits in mode can be set: 0x%x", newpath, oflags));
135 138
136 if(tflag || vflag)139 if(tflag || vflag)
137 print("%s\n", newpath);140 sys->print("%s\n", newpath);
138 141
139 if(me != nil) {142 if(me != nil) {
140 if(!tflag)143 if(!tflag)
@@ -148,10 +151,10 @@ walk(path: string, vd: ref Vacdir) · 7 unmodified lines
148 say("writing file");151 say("writing file");
149 fd := create(newpath, sys->OWRITE, de);152 fd := create(newpath, sys->OWRITE, de);
150 if(fd == nil)153 if(fd == nil)
151 error(sprint("creating %s: %r", newpath));154 fail(sprint("creating %s: %r", newpath));
152 bio := bufio->fopen(fd, bufio->OWRITE);155 bio := bufio->fopen(fd, bufio->OWRITE);
153 if(bio == nil)156 if(bio == nil)
154 error(sprint("bufio fopen %s: %r", newpath));157 fail(sprint("bufio fopen %s: %r", newpath));
155 158
156 buf := array[sys->ATOMICIO] of byte;159 buf := array[sys->ATOMICIO] of byte;
157 vf := Vacfile.new(session, e);160 vf := Vacfile.new(session, e);
@@ -160,15 +163,15 @@ walk(path: string, vd: ref Vacdir) · 2 unmodified lines
160 if(rn == 0)163 if(rn == 0)
161 break;164 break;
162 if(rn < 0)165 if(rn < 0)
163 error(sprint("reading vac %s: %r", newpath));166 fail(sprint("reading vac %s: %r", newpath));
164 wn := bio.write(buf, rn);167 wn := bio.write(buf, rn);
165 if(wn != rn)168 if(wn != rn)
166 error(sprint("writing local %s: %r", newpath));169 fail(sprint("writing local %s: %r", newpath));
167 }170 }
168 bok := bio.flush();171 bok := bio.flush();
169 bio.close();172 bio.close();
170 if(bok == bufio->ERROR || bok == bufio->EOF)173 if(bok == bufio->ERROR || bok == bufio->EOF)
171 error(sprint("bufio close: %r"));174 fail(sprint("bufio close: %r"));
172 175
173 if(pflag) {176 if(pflag) {
174 d := sys->nulldir;177 d := sys->nulldir;
@@ -181,19 +184,22 @@ walk(path: string, vd: ref Vacdir) · 6 unmodified lines
181 }184 }
182}185}
183 186
184error(s: string)187say(s: string)
185{188{
186 fprint(fildes(2), "%s\n", s);189 if(dflag)
187 raise "fail:"+s;190 warn(s);
188}191}
189 192
193fd2: ref Sys->FD;
190warn(s: string)194warn(s: string)
191{195{
192 fprint(fildes(2), "%s\n", s);196 if(fd2 == nil)
197 fd2 = sys->fildes(2);
198 sys->fprint(fd2, "%s\n", s);
193}199}
194 200
195say(s: string)201fail(s: string)
196{202{
197 if(dflag)203 warn(s);
198 warn(s);204 raise "fail:"+s;
199}205}
appl/cmd/vacput.b+158−87
@@ -2,81 +2,113 @@ implement Vacput; · 1 unmodified line
2 2
3include "sys.m";3include "sys.m";
4 sys: Sys;4 sys: Sys;
5 sprint: import sys;
5include "draw.m";6include "draw.m";
7include "arg.m";
6include "daytime.m";8include "daytime.m";
9 dt: Daytime;
7include "bufio.m";10include "bufio.m";
8 bufio: Bufio;11 bufio: Bufio;
9 Iobuf: import bufio;12 Iobuf: import bufio;
10include "arg.m";13include "dial.m";
14 dial: Dial;
11include "string.m";15include "string.m";
16 str: String;
17include "tables.m";
18 tables: Tables;
19 Strhash: import tables;
12include "venti.m";20include "venti.m";
21 venti: Venti;
22 Root, Entry, Score, Session: import venti;
13include "vac.m";23include "vac.m";
14 24 vac: Vac;
15daytime: Daytime;25 Direntry, File, Sink, MSink: import vac;
16str: String;
17venti: Venti;
18vac: Vac;
19
20print, sprint, fprint, fildes: import sys;
21Score, Session: import venti;
22Roottype, Dirtype, Pointertype0, Datatype: import venti;
23Root, Entry, Direntry, Metablock, Metaentry, Entrysize, File, Sink, MSink: import vac;
24 26
25Vacput: module {27Vacput: module {
26 init: fn(nil: ref Draw->Context, args: list of string);28 init: fn(nil: ref Draw->Context, args: list of string);
27};29};
28 30
29addr := "net!$venti!venti";31addr := "$venti";
30dflag := 0;32dflag: int;
31vflag := 0;33iflag: int;
34vflag: int;
35xflag: int;
32blocksize := vac->Dsize;36blocksize := vac->Dsize;
37uid: string;
38gid: string;
39
40pathgen: big;
41
42bout: ref Iobuf;
33session: ref Session;43session: ref Session;
34name := "vac";44name := "vac";
45itab,
46xtab: ref Strhash[string]; # include/exclude paths
35 47
36init(nil: ref Draw->Context, args: list of string)48init(nil: ref Draw->Context, args: list of string)
37{49{
38 sys = load Sys Sys->PATH;50 sys = load Sys Sys->PATH;
39 daytime = load Daytime Daytime->PATH;51 dt = load Daytime Daytime->PATH;
40 bufio = load Bufio Bufio->PATH;52 bufio = load Bufio Bufio->PATH;
41 arg := load Arg Arg->PATH;53 arg := load Arg Arg->PATH;
54 dial = load Dial Dial->PATH;
42 str = load String String->PATH;55 str = load String String->PATH;
56 tables = load Tables Tables->PATH;
43 venti = load Venti Venti->PATH;57 venti = load Venti Venti->PATH;
44 vac = load Vac Vac->PATH;58 vac = load Vac Vac->PATH;
45 if(venti == nil || vac == nil)59 if(venti == nil || vac == nil)
46 error("loading venti,vac");60 fail("loading venti,vac");
47 venti->init();61 venti->init();
48 vac->init();62 vac->init();
49 63
50 arg->init(args);64 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 ...");
52 while((c := arg->opt()) != 0)66 while((c := arg->opt()) != 0)
53 case c {67 case c {
54 'a' => addr = arg->earg();68 'a' => addr = arg->earg();
55 'b' => blocksize = int arg->earg();69 'b' => blocksize = int arg->earg();
56 'n' => name = arg->earg();70 'n' => name = arg->earg();
57 'd' => dflag++;71 'd' => vac->dflag = dflag++;
58 vac->dflag++;72 'i' => iflag++;
59 'v' => vflag++;73 'v' => vflag++;
60 * => warn(sprint("bad option: -%c", c));74 'x' => xflag++;
61 arg->usage();75 'g' => gid = arg->earg();
76 'u' => uid = arg->earg();
77 * => arg->usage();
62 }78 }
63 args = arg->argv();79 args = arg->argv();
64 if(len args == 0)80 if(len args == 0)
65 arg->usage();81 arg->usage();
82 if(iflag && xflag) {
83 warn("cannot have both -i and -x");
84 arg->usage();
85 }
66 86
67 (cok, conn) := sys->dial(addr, nil);87 if(vflag)
68 if(cok < 0)88 bout = bufio->fopen(sys->fildes(1), bufio->OWRITE);
69 error(sprint("dialing %s: %r", addr));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));
70 say("have connection");102 say("have connection");
71 103
72 fd := conn.dfd;104 fd := cc.dfd;
73 session = Session.new(fd);105 session = Session.new(fd);
74 if(session == nil)106 if(session == nil)
75 error(sprint("handshake: %r"));107 fail(sprint("handshake: %r"));
76 say("have handshake");108 say("have handshake");
77 109
78 topde: ref Direntry;110 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)) {
80 topde = Direntry.mk(d);112 topde = Direntry.mk(d);
81 topde.elem = name;113 topde.elem = name;
82 } else {114 } else {
@@ -86,7 +118,12 @@ init(nil: ref Draw->Context, args: list of string) · 3 unmodified lines
86 topde.mode = 8r777|Vac->Modedir;118 topde.mode = 8r777|Vac->Modedir;
87 topde.mtime = topde.atime = 0;119 topde.mtime = topde.atime = 0;
88 }120 }
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();
90 127
91 s := Sink.new(session, blocksize);128 s := Sink.new(session, blocksize);
92 ms := MSink.new(session, blocksize);129 ms := MSink.new(session, blocksize);
@@ -94,66 +131,93 @@ init(nil: ref Draw->Context, args: list of string) · 1 unmodified line
94 writepath(hd args, s, ms);131 writepath(hd args, s, ms);
95 say("tree written");132 say("tree written");
96 133
134 if(vflag && bout.flush() == bufio->ERROR)
135 fail(sprint("write stdout: %r"));
136
97 e0 := s.finish();137 e0 := s.finish();
98 if(e0 == nil)138 if(e0 == nil)
99 error(sprint("writing top entry: %r"));139 fail(sprint("writing top entry: %r"));
100 e1 := ms.finish();140 e1 := ms.finish();
101 if(e1 == nil)141 if(e1 == nil)
102 error(sprint("writing top meta entry: %r"));142 fail(sprint("writing top meta entry: %r"));
103 say(sprint("top entries written (%s, %s)", e0.score.text(), e1.score.text()));143 topde.qidspace = 1;
144 topde.qidoff = big 0;
145 topde.qidmax = pathgen;
104 s2 := MSink.new(session, blocksize);146 s2 := MSink.new(session, blocksize);
105 if(s2.add(topde) < 0)147 if(s2.add(topde) < 0)
106 error(sprint("adding direntry for top entries: %r"));148 fail(sprint("adding direntry for top entries: %r"));
107 e2 := s2.finish();149 e2 := s2.finish();
108 say("top meta entry written, "+e2.score.text());150 say("top meta entry written, "+e2.score.text());
109 151
110 td := array[Entrysize*3] of byte;152 td := array[venti->Entrysize*3] of byte;
111 td[0*Entrysize:] = e0.pack();153 td[0*venti->Entrysize:] = e0.pack();
112 td[1*Entrysize:] = e1.pack();154 td[1*venti->Entrysize:] = e1.pack();
113 td[2*Entrysize:] = e2.pack();155 td[2*venti->Entrysize:] = e2.pack();
114 (tok, tscore) := session.write(Dirtype, td);156 (tok, tscore) := session.write(venti->Dirtype, td);
115 if(tok < 0)157 if(tok < 0)
116 error(sprint("writing top-level entries: %r"));158 fail(sprint("writing top-level entries: %r"));
117 say("top entry written, "+tscore.text());
118 159
119 root := Root.new(name, "vac", tscore, blocksize, nil);160 root := ref Root(venti->Rootversion, name, "vac", tscore, blocksize, nil);
120 rd := root.pack();161 rd := root.pack();
121 if(rd == nil)162 if(rd == nil)
122 error(sprint("root pack: %r"));163 fail(sprint("root pack: %r"));
123 (rok, rscore) := session.write(Roottype, rd);164 (rok, rscore) := session.write(venti->Roottype, rd);
124 if(rok < 0)165 if(rok < 0)
125 error(sprint("writing root score: %r"));166 fail(sprint("writing root score: %r"));
126 say("root written, "+rscore.text());167 sys->print("vac:%s\n", rscore.text());
127 print("vac:%s\n", rscore.text());
128 if(session.sync() < 0)168 if(session.sync() < 0)
129 error(sprint("syncing server: %r"));169 fail(sprint("syncing server: %r"));
170}
171
172readpaths(): 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
189usepath(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;
130}196}
131 197
132writepath(path: string, s: ref Sink, ms: ref MSink)198writepath(path: string, s: ref Sink, ms: ref MSink)
133{199{
134 if(vflag)200 if(!usepath(path))
135 print("%s\n", path);201 return;
136say("writepath "+path);202
203 if(vflag && bout.puts(path+"\n") == bufio->ERROR)
204 fail(sprint("write stdout: %r"));
205
137 fd := sys->open(path, sys->OREAD);206 fd := sys->open(path, sys->OREAD);
138 if(fd == nil)207 if(fd == nil)
139 error(sprint("opening %s: %r", path));208 fail(sprint("opening %s: %r", path));
140 (ok, dir) := sys->fstat(fd);209 (ok, dir) := sys->fstat(fd);
141 if(ok < 0)210 if(ok < 0)
142 error(sprint("fstat %s: %r", path));211 fail(sprint("fstat %s: %r", path));
143say("writepath: file opened");212 if(dir.mode&sys->DMAUTH)
144 if(dir.mode&sys->DMAUTH) {213 return warn(path+": is auth file, skipping");
145 warn(path+": is auth file, skipping");214 if(dir.mode&sys->DMTMP)
146 return;215 return warn(path+": is temporary file, skipping");
147 }
148 if(dir.mode&sys->DMTMP) {
149 warn(path+": is temporary file, skipping");
150 return;
151 }
152 216
153 e, me: ref Entry;217 e, me: ref Entry;
154 de: ref Direntry;218 de: ref Direntry;
219 qid := pathgen++;
155 if(dir.mode & sys->DMDIR) {220 if(dir.mode & sys->DMDIR) {
156say("writepath: file is dir");
157 ns := Sink.new(session, blocksize);221 ns := Sink.new(session, blocksize);
158 nms := MSink.new(session, blocksize);222 nms := MSink.new(session, blocksize);
159 for(;;) {223 for(;;) {
@@ -161,7 +225,7 @@ say("writepath: file is dir"); · 1 unmodified line
161 if(n == 0)225 if(n == 0)
162 break;226 break;
163 if(n < 0)227 if(n < 0)
164 error(sprint("dirread %s: %r", path));228 fail(sprint("dirread %s: %r", path));
165 for(i := 0; i < len dirs; i++) {229 for(i := 0; i < len dirs; i++) {
166 d := dirs[i];230 d := dirs[i];
167 npath := path+"/"+d.name;231 npath := path+"/"+d.name;
@@ -170,45 +234,49 @@ say("writepath: file is dir"); · 2 unmodified lines
170 }234 }
171 e = ns.finish();235 e = ns.finish();
172 if(e == nil)236 if(e == nil)
173 error(sprint("error flushing dirsink for %s: %r", path));237 fail(sprint("error flushing dirsink for %s: %r", path));
174 me = nms.finish();238 me = nms.finish();
175 if(me == nil)239 if(me == nil)
176 error(sprint("error flushing metasink for %s: %r", path));240 fail(sprint("error flushing metasink for %s: %r", path));
177 } else {241 } else {
178say("writepath: file is normale file");
179 e = writefile(path, fd);242 e = writefile(path, fd);
180 if(e == nil)243 if(e == nil)
181 error(sprint("error flushing filesink for %s: %r", path));244 fail(sprint("error flushing filesink for %s: %r", path));
182 }245 }
183say("writepath: wrote path, "+e.score.text());
184 246
247 case dir.name {
248 "/" => dir.name = "root";
249 "." => dir.name = "dot";
250 }
185 de = Direntry.mk(dir);251 de = Direntry.mk(dir);
186say("writepath: have direntry");252 de.qid = qid;
253 if(uid != nil)
254 de.uid = uid;
255 if(gid != nil)
256 de.gid = gid;
187 257
188 i := s.add(e);258 i := s.add(e);
189 if(i < 0)259 if(i < 0)
190 error(sprint("adding entry to sink: %r"));260 fail(sprint("adding entry to sink: %r"));
191 mi := 0;261 mi := 0;
192 if(me != nil)262 if(me != nil)
193 mi = s.add(me);263 mi = s.add(me);
194 if(mi < 0)264 if(mi < 0)
195 error(sprint("adding mentry to sink: %r"));265 fail(sprint("adding mentry to sink: %r"));
196 de.entry = i;266 de.entry = i;
197 de.mentry = mi;267 de.mentry = mi;
198 i = ms.add(de);268 i = ms.add(de);
199 if(i < 0)269 if(i < 0)
200 error(sprint("adding direntry to msink: %r"));270 fail(sprint("adding direntry to msink: %r"));
201say("writepath done");
202}271}
203 272
204writefile(path: string, fd: ref Sys->FD): ref Entry273writefile(path: string, fd: ref Sys->FD): ref Entry
205{274{
206 bio := bufio->fopen(fd, bufio->OREAD);275 bio := bufio->fopen(fd, bufio->OREAD);
207 if(bio == nil)276 if(bio == nil)
208 error(sprint("bufio opening %s: %r", path));277 fail(sprint("bufio opening %s: %r", path));
209 say(sprint("bufio opened path %s", path));
210 278
211 f := File.new(session, Datatype, blocksize);279 f := File.new(session, venti->Datatype, blocksize);
212 for(;;) {280 for(;;) {
213 buf := array[blocksize] of byte;281 buf := array[blocksize] of byte;
214 n := 0;282 n := 0;
@@ -218,13 +286,12 @@ writefile(path: string, fd: ref Sys->FD): ref Entry · 3 unmodified lines
218 if(have == 0)286 if(have == 0)
219 break;287 break;
220 if(have < 0)288 if(have < 0)
221 error(sprint("reading %s: %r", path));289 fail(sprint("reading %s: %r", path));
222 n += have;290 n += have;
223 }291 }
224 say(sprint("have buf, length %d", n));
225 292
226 if(f.write(buf[:n]) < 0)293 if(f.write(buf[:n]) < 0)
227 error(sprint("writing %s: %r", path));294 fail(sprint("writing %s: %r", path));
228 if(n != len buf)295 if(n != len buf)
229 break;296 break;
230 }297 }
@@ -234,21 +301,19 @@ writefile(path: string, fd: ref Sys->FD): ref Entry · 3 unmodified lines
234 301
235user(): string302user(): string
236{303{
237 if((fd := sys->open("/dev/user", Sys->OREAD)) != nil304 fd := sys->open("/dev/user", Sys->OREAD);
238 && (n := sys->read(fd, d := array[128] of byte, len d)) > 0)305 if(fd != nil)
306 if((n := sys->read(fd, d := array[128] of byte, len d)) > 0)
239 return string d[:n];307 return string d[:n];
240 return "nobody";308 return "nobody";
241}309}
242 310
243error(s: string)311fd2: ref Sys->FD;
244{
245 warn(s);
246 raise "fail:"+s;
247}
248
249warn(s: string)312warn(s: string)
250{313{
251 fprint(fildes(2), "%s\n", s);314 if(fd2 == nil)
315 fd2 = sys->fildes(2);
316 sys->fprint(fd2, "%s\n", s);
252}317}
253 318
254say(s: string)319say(s: string)
@@ -256,3 +321,9 @@ say(s: string) · 1 unmodified line
256 if(dflag)321 if(dflag)
257 warn(s);322 warn(s);
258}323}
324
325fail(s: string)
326{
327 warn(s);
328 raise "fail:"+s;
329}
appl/lib/vac.b+121−214
@@ -1,19 +1,17 @@
1implement Vac;1implement Vac;
2 2
3include "sys.m";3include "sys.m";
4 sys: Sys;
5 sprint: import sys;
4include "venti.m";6include "venti.m";
7 venti: Venti;
8 Entrysize, Scoresize, Roottype, Dirtype, Pointertype0, Datatype: import venti;
9 Root, Entry, Score, Session: import venti;
5include "vac.m";10include "vac.m";
6 11
7sys: Sys;
8venti: Venti;
9
10werrstr, sprint, fprint, fildes: import sys;
11Roottype, Dirtype, Pointertype0, Datatype: import venti;
12Score, Session, Scoresize: import venti;
13 12
14dflag = 0;13dflag = 0;
15 14
16# from venti.b
17BIT8SZ: con 1;15BIT8SZ: con 1;
18BIT16SZ: con 2;16BIT16SZ: con 2;
19BIT32SZ: con 4;17BIT32SZ: con 4;
@@ -32,7 +30,6 @@ blankdirentry: Direntry; · 12 unmodified lines
32blankmetablock: Metablock;30blankmetablock: Metablock;
33blankmetaentry: Metaentry;31blankmetaentry: Metaentry;
34 32
35
36init()33init()
37{34{
38 sys = load Sys Sys->PATH;35 sys = load Sys Sys->PATH;
@@ -40,158 +37,9 @@ init() · 1 unmodified line
40 venti->init();37 venti->init();
41}38}
42 39
43pstring(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
53gstring(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
67gtstring(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
79Root.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
84Root.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
110Root.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
135Entry.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
140Entry.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
160Entry.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
192Direntry.new(): ref Direntry40Direntry.new(): ref Direntry
193{41{
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);
195}43}
196 44
197Direntry.mk(d: Sys->Dir): ref Direntry45Direntry.mk(d: Sys->Dir): ref Direntry
@@ -206,7 +54,7 @@ Direntry.mk(d: Sys->Dir): ref Direntry · 8 unmodified lines
206 mode |= Modedir;54 mode |= Modedir;
207 if(d.mode&sys->DMTMP)55 if(d.mode&sys->DMTMP)
208 mode |= Modetemp;56 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);
210}58}
211 59
212Direntry.mkdir(de: self ref Direntry): ref Sys->Dir60Direntry.mkdir(de: self ref Direntry): ref Sys->Dir
@@ -233,8 +81,14 @@ strlen(s: string): int · 20 unmodified lines
233 81
234Direntry.pack(de: self ref Direntry): array of byte82Direntry.pack(de: self ref Direntry): array of byte
235{83{
236 # assume version 984 if(de.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?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;
238 92
239 d := array[length] of byte;93 d := array[length] of byte;
240 i := 0;94 i := 0;
@@ -256,8 +110,14 @@ Direntry.pack(de: self ref Direntry): array of byte · 15 unmodified lines
256 i = p32(d, i, de.ctime);110 i = p32(d, i, de.ctime);
257 i = p32(d, i, de.atime);111 i = p32(d, i, de.atime);
258 i = p32(d, i, de.mode);112 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 }
259 if(i != len d) {119 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));
261 return nil;121 return nil;
262 }122 }
263 return d;123 return d;
@@ -271,12 +131,12 @@ Direntry.unpack(d: array of byte): ref Direntry · 7 unmodified lines
271 magic: int;131 magic: int;
272 (magic, i) = eg32(d, i);132 (magic, i) = eg32(d, i);
273 if(magic != Direntrymagic) {133 if(magic != Direntrymagic) {
274 werrstr(sprint("bad magic (%x, want %x)", magic, Direntrymagic));134 sys->werrstr(sprint("bad magic (%x, want %x)", magic, Direntrymagic));
275 return nil;135 return nil;
276 }136 }
277 (de.version, i) = eg16(d, i);137 (de.version, i) = eg16(d, i);
278 if(de.version != 8 && de.version != 9) {138 if(de.version != 8 && de.version != 9) {
279 werrstr(sprint("bad version (%d)", de.version));139 sys->werrstr(sprint("bad version (%d)", de.version));
280 return nil;140 return nil;
281 }141 }
282 (de.elem, i) = egstring(d, i);142 (de.elem, i) = egstring(d, i);
@@ -309,12 +169,28 @@ Direntry.unpack(d: array of byte): ref Direntry · 26 unmodified lines
309 de.emode |= sys->DMDIR;169 de.emode |= sys->DMDIR;
310 if(de.mode&Modetemp)170 if(de.mode&Modetemp)
311 de.emode |= sys->DMTMP;171 de.emode |= sys->DMTMP;
312 if(de.version == 9)172 while(i < len d) {
313 ; # xxx handle qid space?, can be in here173 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 }
314 return de;190 return de;
315 } exception e {191 } exception e {
316 "too small:*" =>192 "too small:*" =>
317 werrstr("direntry "+e);193 sys->werrstr("direntry "+e);
318 return nil;194 return nil;
319 * =>195 * =>
320 raise e;196 raise e;
@@ -340,13 +216,13 @@ Metablock.pack(mb: self ref Metablock, d: array of byte) · 19 unmodified lines
340Metablock.unpack(d: array of byte): ref Metablock216Metablock.unpack(d: array of byte): ref Metablock
341{217{
342 if(len d < Metablocksize) {218 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));
344 return nil;220 return nil;
345 }221 }
346 i := 0;222 i := 0;
347 magic := g32(d, i);223 magic := g32(d, i);
348 if(magic != Metablockmagic && magic != Metablockmagic+1) {224 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));
350 return nil;226 return nil;
351 }227 }
352 i += BIT32SZ;228 i += BIT32SZ;
@@ -361,7 +237,7 @@ Metablock.unpack(d: array of byte): ref Metablock · 8 unmodified lines
361 mb.nindex = g16(d, i);237 mb.nindex = g16(d, i);
362 i += BIT16SZ;238 i += BIT16SZ;
363 if(mb.nindex == 0) {239 if(mb.nindex == 0) {
364 werrstr("bad metablock, nindex=0");240 sys->werrstr("bad metablock, nindex=0");
365 return nil;241 return nil;
366 }242 }
367 return mb;243 return mb;
@@ -378,7 +254,7 @@ Metaentry.unpack(d: array of byte, i: int): ref Metaentry · 10 unmodified lines
378{254{
379 o := Metablocksize+i*Metaentrysize;255 o := Metablocksize+i*Metaentrysize;
380 if(o+Metaentrysize > len d) {256 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));
382 return nil;258 return nil;
383 }259 }
384 260
@@ -388,7 +264,7 @@ Metaentry.unpack(d: array of byte, i: int): ref Metaentry · 3 unmodified lines
388 me.size = g16(d, o);264 me.size = g16(d, o);
389 o += BIT16SZ;265 o += BIT16SZ;
390 if(me.offset+me.size > len d) {266 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));
392 return nil;268 return nil;
393 }269 }
394 return me;270 return me;
@@ -435,14 +311,14 @@ fflush(f: ref File, last: int): (int, ref Entry) · 40 unmodified lines
435 if(!last && !f.p[i].full())311 if(!last && !f.p[i].full())
436 return (0, nil);312 return (0, nil);
437 if(last && f.p[i].o == Scoresize) {313 if(last && f.p[i].o == Scoresize) {
438 flags := Entryactive;314 flags := venti->Entryactive;
439 if(f.dtype == Dirtype)315 if(f.dtype == Dirtype)
440 flags |= Entrydir;316 flags |= venti->Entrydir;
441 flags |= i<<Entrydepthshift;317 flags |= i<<venti->Entrydepthshift;
442 score := Score(f.p[i].data());318 score := Score(f.p[i].data());
443 if(len score.a == 0)319 if(len score.a == 0)
444 score = Score.zero();320 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));
446 }322 }
447 (ok, score) := f.s.write(Pointertype0+i, f.p[i].data());323 (ok, score) := f.s.write(Pointertype0+i, f.p[i].data());
448 if(ok < 0)324 if(ok < 0)
@@ -456,7 +332,7 @@ fflush(f: ref File, last: int): (int, ref Entry) · 7 unmodified lines
456 }332 }
457 f.p[i+1].add(score);333 f.p[i+1].add(score);
458 }334 }
459 werrstr("internal error in fflush");335 sys->werrstr("internal error in fflush");
460 return (-1, nil);336 return (-1, nil);
461}337}
462 338
@@ -601,7 +477,7 @@ MSink.add(m: self ref MSink, de: ref Direntry): int · 138 unmodified lines
601 d := de.pack();477 d := de.pack();
602 if(d == nil)478 if(d == nil)
603 return -1;479 return -1;
604say(sprint("msink: adding direntry, length %d", len d));480if(dflag) say(sprint("msink: adding direntry, length %d", len d));
605 if(Metablocksize+len m.l*Metaentrysize+m.nde + Metaentrysize+len d > len m.de)481 if(Metablocksize+len m.l*Metaentrysize+m.nde + Metaentrysize+len d > len m.de)
606 if(mflush(m, 0) < 0)482 if(mflush(m, 0) < 0)
607 return -1;483 return -1;
@@ -621,7 +497,7 @@ MSink.finish(m: self ref MSink): ref Entry · 13 unmodified lines
621Source.new(s: ref Session, e: ref Entry): ref Source497Source.new(s: ref Session, e: ref Entry): ref Source
622{498{
623 dsize := e.dsize;499 dsize := e.dsize;
624 if(e.flags&Entrydir)500 if(e.flags&venti->Entrydir)
625 dsize = Entrysize*(dsize/Entrysize);501 dsize = Entrysize*(dsize/Entrysize);
626 return ref Source(s, e, dsize);502 return ref Source(s, e, dsize);
627}503}
@@ -660,7 +536,7 @@ Source.get(s: self ref Source, i: big, d: array of byte): int · 32 unmodified lines
660 dtype := Pointertype0+depth-1;536 dtype := Pointertype0+depth-1;
661 if(depth == 0) {537 if(depth == 0) {
662 dtype = Datatype;538 dtype = Datatype;
663 if(s.e.flags & Entrydir)539 if(s.e.flags & venti->Entrydir)
664 dtype = Dirtype;540 dtype = Dirtype;
665 bsize = want;541 bsize = want;
666 }542 }
@@ -714,11 +590,11 @@ Vacfile.read(v: self ref Vacfile, d: array of byte, n: int): int · 47 unmodified lines
714Vacfile.pread(v: self ref Vacfile, d: array of byte, n: int, offset: big): int590Vacfile.pread(v: self ref Vacfile, d: array of byte, n: int, offset: big): int
715{591{
716 dsize := v.s.dsize;592 dsize := v.s.dsize;
717say(sprint("vf.preadn, len d %d, n %d, offset %bd", len d, n, offset));593if(dflag) say(sprint("vf.preadn, len d %d, n %d, offset %bd", len d, n, offset));
718 have := v.s.get(big (offset/big dsize), buf := array[dsize] of byte);594 have := v.s.get(big (offset/big dsize), buf := array[dsize] of byte);
719 if(have <= 0)595 if(have <= 0)
720 return have;596 return have;
721say(sprint("vacfile.pread: have=%d dsize=%d", have, dsize));597if(dflag) say(sprint("vacfile.pread: have=%d dsize=%d", have, dsize));
722 o := int (offset % big dsize);598 o := int (offset % big dsize);
723 have -= o;599 have -= o;
724 if(have > n)600 if(have > n)
@@ -752,7 +628,7 @@ mecmp(d: array of byte, i: int, elem: string, fromfossil: int): (int, int) · 27 unmodified lines
752 n := g16(d, o);628 n := g16(d, o);
753 o += BIT16SZ;629 o += BIT16SZ;
754 if(o+n > len d) {630 if(o+n > len d) {
755 werrstr("bad elem in direntry");631 sys->werrstr("bad elem in direntry");
756 return (0, 1);632 return (0, 1);
757 }633 }
758 return (elemcmp(d[o:o+n], array of byte elem, fromfossil), 0);634 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
801 return de;677 return de;
802 i++;678 i++;
803 }679 }
804 werrstr(sprint("no such file or directory"));680 sys->werrstr(sprint("no such file or directory"));
805 return nil;681 return nil;
806}682}
807 683
808vfreadentry(vf: ref Vacfile, entry: int): ref Entry684vfreadentry(vf: ref Vacfile, entry: int): ref Entry
809{685{
810say(sprint("vfreadentry: reading entry=%d", entry));686if(dflag) say(sprint("vfreadentry: reading entry=%d", entry));
811 ebuf := array[Entrysize] of byte;687 ebuf := array[Entrysize] of byte;
812 n := vf.pread(ebuf, len ebuf, big entry*big Entrysize);688 n := vf.pread(ebuf, len ebuf, big entry*big Entrysize);
813 if(n < 0)689 if(n < 0)
814 return nil;690 return nil;
815 if(n != len ebuf) {691 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));
817 return nil;693 return nil;
818 }694 }
819 e := Entry.unpack(ebuf);695 e := Entry.unpack(ebuf);
820 if(~e.flags&Entryactive) {696 if(e == nil)
821 werrstr("entry not active");697 return nil;
698 if(~e.flags&venti->Entryactive) {
699 sys->werrstr("entry not active");
822 return nil;700 return nil;
823 }701 }
824 # p9p writes archives with Entrylocal set?702 # p9p writes archives with Entrylocal set?
825 if(0 && e.flags&Entrylocal) {703 if(0 && e.flags&venti->Entrylocal) {
826 werrstr("entry is local");704 sys->werrstr("entry is local");
827 return nil;705 return nil;
828 }706 }
829say(sprint("vreadentry: have entry, score=%s", e.score.text()));707if(dflag) say(sprint("vreadentry: have entry, score=%s", e.score.text()));
830 return e;708 return e;
831}709}
832 710
833Vacdir.open(vd: self ref Vacdir, de: ref Direntry): (ref Entry, ref Entry)711Vacdir.open(vd: self ref Vacdir, de: ref Direntry): (ref Entry, ref Entry)
834{712{
835say(sprint("vacdir.open: opening entry=%d", de.entry));713if(dflag) say(sprint("vacdir.open: opening entry=%d", de.entry));
836 e := vfreadentry(vd.vf, de.entry);714 e := vfreadentry(vd.vf, de.entry);
837 if(e == nil)715 if(e == nil)
838 return (nil, nil);716 return (nil, nil);
839 isdir1 := de.mode & Modedir;717 isdir1 := de.mode & Modedir;
840 isdir2 := e.flags & Entrydir;718 isdir2 := e.flags & venti->Entrydir;
841 if(isdir1 && !isdir2 || !isdir1 && isdir2) {719 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");
843 return (nil, nil);721 return (nil, nil);
844 }722 }
845say(sprint("vacdir.open: have entry, score=%s size=%bd", e.score.text(), e.size));723if(dflag) say(sprint("vacdir.open: have entry, score=%s size=%bd", e.score.text(), e.size));
846 me: ref Entry;724 me: ref Entry;
847 if(de.mode&Modedir) {725 if(de.mode&Modedir) {
848 me = vfreadentry(vd.vf, de.mentry);726 me = vfreadentry(vd.vf, de.mentry);
849 if(me == nil)727 if(me == nil)
850 return (nil, nil);728 return (nil, nil);
851say(sprint("vacdir.open: have mentry, score=%s size=%bd", me.score.text(), e.size));729if(dflag) say(sprint("vacdir.open: have mentry, score=%s size=%bd", me.score.text(), e.size));
852 }730 }
853 return (e, me);731 return (e, me);
854}732}
@@ -860,8 +738,10 @@ readdirentry(buf: array of byte, i: int, allowroot: int): ref Direntry · 5 unmodified lines
860 return nil;738 return nil;
861 o := me.offset;739 o := me.offset;
862 de := Direntry.unpack(buf[o:o+me.size]);740 de := Direntry.unpack(buf[o:o+me.size]);
741 if(de == nil)
742 return nil;
863 if(badelem(de.elem) && !(allowroot && de.elem == "/")) {743 if(badelem(de.elem) && !(allowroot && de.elem == "/")) {
864 werrstr(sprint("bad direntry: %s", de.elem));744 sys->werrstr(sprint("bad direntry: %s", de.elem));
865 return nil;745 return nil;
866 }746 }
867 return de;747 return de;
@@ -882,12 +762,12 @@ badelem(elem: string): int · 14 unmodified lines
882 762
883vdreaddir(vd: ref Vacdir, allowroot: int): (int, ref Direntry)763vdreaddir(vd: ref Vacdir, allowroot: int): (int, ref Direntry)
884{764{
885say(sprint("vdreaddir: ms.e.size=%bd vd.p=%bd vd.i=%d", vd.ms.e.size, vd.p, vd.i));765if(dflag) say(sprint("vdreaddir: ms.e.size=%bd vd.p=%bd vd.i=%d", vd.ms.e.size, vd.p, vd.i));
886 dsize := vd.ms.dsize;766 dsize := vd.ms.dsize;
887 n := vd.ms.get(vd.p, buf := array[dsize] of byte);767 n := vd.ms.get(vd.p, buf := array[dsize] of byte);
888 if(n <= 0)768 if(n <= 0)
889 return (n, nil);769 return (n, nil);
890say(sprint("vdreaddir: have buf, length=%d e.size=%bd", n, vd.ms.e.size));770if(dflag) say(sprint("vdreaddir: have buf, length=%d e.size=%bd", n, vd.ms.e.size));
891 mb := Metablock.unpack(buf);771 mb := Metablock.unpack(buf);
892 if(mb == nil)772 if(mb == nil)
893 return (-1, nil);773 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
899 vd.p++;779 vd.p++;
900 vd.i = 0;780 vd.i = 0;
901 }781 }
902say("vdreaddir: have entry");782if(dflag) say("vdreaddir: have entry");
903 return (1, de);783 return (1, de);
904}784}
905 785
@@ -918,20 +798,18 @@ Vacdir.rewind(vd: self ref Vacdir) · 12 unmodified lines
918 798
919vdroot(session: ref Session, score: Venti->Score): (ref Vacdir, ref Direntry, string)799vdroot(session: ref Session, score: Venti->Score): (ref Vacdir, ref Direntry, string)
920{800{
921 d := session.read(score, Roottype, Rootsize);801 d := session.read(score, venti->Roottype, venti->Rootsize);
922 if(d == nil)802 if(d == nil)
923 return (nil, nil, sprint("reading vac score: %r"));803 return (nil, nil, sprint("reading vac score: %r"));
924 r := Root.unpack(d);804 r := Root.unpack(d);
925 if(r == nil)805 if(r == nil)
926 return (nil, nil, sprint("bad vac root block: %r"));806 return (nil, nil, sprint("bad vac root block: %r"));
927 say("have root");
928 topscore := r.score;807 topscore := r.score;
929 808
930 d = session.read(topscore, Dirtype, 3*Entrysize);809 d = session.read(topscore, Dirtype, 3*Entrysize);
931 if(d == nil)810 if(d == nil)
932 return (nil, nil, sprint("reading rootdir score: %r"));811 return (nil, nil, sprint("reading rootdir score: %r"));
933 if(len d != 3*Entrysize) {812 if(len d != 3*Entrysize) {
934 say("top entries not in directory of 3 elements, assuming it's from fossil");
935 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 score813 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
936 return (nil, nil, sprint("bad fossil rootdir, have %d bytes, need %d or %d", len d, Entrysize, 2*Entrysize));814 return (nil, nil, sprint("bad fossil rootdir, have %d bytes, need %d or %d", len d, Entrysize, 2*Entrysize));
937 e := Entry.unpack(d[:Entrysize]);815 e := Entry.unpack(d[:Entrysize]);
@@ -941,9 +819,7 @@ vdroot(session: ref Session, score: Venti->Score): (ref Vacdir, ref Direntry, st · 3 unmodified lines
941 d = session.read(topscore, Dirtype, 3*Entrysize);819 d = session.read(topscore, Dirtype, 3*Entrysize);
942 if(d == nil)820 if(d == nil)
943 return (nil, nil, sprint("reading fossil rootdir block: %r"));821 return (nil, nil, sprint("reading fossil rootdir block: %r"));
944 say("have fossil top entries");
945 }822 }
946 say("have top entries");
947 823
948 e := array[3] of ref Entry;824 e := array[3] of ref Entry;
949 j := 0;825 j := 0;
@@ -953,14 +829,13 @@ vdroot(session: ref Session, score: Venti->Score): (ref Vacdir, ref Direntry, st · 3 unmodified lines
953 return (nil, nil, sprint("reading root entry %d: %r", j));829 return (nil, nil, sprint("reading root entry %d: %r", j));
954 j++;830 j++;
955 }831 }
956 say("top entries unpacked");832if(dflag) say("top entries unpacked");
957 833
958 mroot := Vacdir.mk(nil, Source.new(session, e[2]));834 mroot := Vacdir.mk(nil, Source.new(session, e[2]));
959 (ok, de) := vdreaddir(mroot, 1);835 (ok, de) := vdreaddir(mroot, 1);
960 if(ok <= 0)836 if(ok <= 0)
961 return (nil, nil, sprint("reading root meta entry: %r"));837 return (nil, nil, sprint("reading root meta entry: %r"));
962 838
963say(sprint("vdroot: new score=%s", score.text()));
964 return (Vacdir.new(session, e[0], e[1]), de, nil);839 return (Vacdir.new(session, e[0], e[1]), de, nil);
965}840}
966 841
@@ -974,6 +849,32 @@ checksize(n: int): int · 7 unmodified lines
974 return 1;849 return 1;
975}850}
976 851
852
853gstring(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
867gtstring(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
977gscore(f: array of byte, i: int): Score878gscore(f: array of byte, i: int): Score
978{879{
979 s := Score(array[Scoresize] of byte);880 s := Score(array[Scoresize] of byte);
@@ -993,16 +894,12 @@ g32(f: array of byte, i: int): int · 13 unmodified lines
993 894
994g48(f: array of byte, i: int): big895g48(f: array of byte, i: int): big
995{896{
996 b1 := (((((int f[i+0] << 8) | int f[i+1]) << 8) | int f[i+2]) << 8) | int f[i+3];897 return big g16(f, i)<<32 | (big g32(f, i+2) & 16rFFFFFFFF);
997 b0 := (int f[i+4] << 8) | int f[i+5];
998 return (big b1 << 16) | big b0;
999}898}
1000 899
1001g64(f: array of byte, i: int): big900g64(f: array of byte, i: int): big
1002{901{
1003 b0 := (((((int f[i+3] << 8) | int f[i+2]) << 8) | int f[i+1]) << 8) | int f[i];902 return big g32(f, i)<<32 | (big g32(f, i+4) & 16rFFFFFFFF);
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);
1006}903}
1007 904
1008p16(d: array of byte, i: int, v: int): int905p16(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
1033 return i+BIT64SZ;930 return i+BIT64SZ;
1034}931}
1035 932
933pstring(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
1036ptstring(d: array of byte, i: int, s: string, l: int): int943ptstring(d: array of byte, i: int, s: string, l: int): int
1037{944{
1038 a := array of byte s;945 a := array of byte s;
@@ -1101,5 +1008,5 @@ eg64(f: array of byte, i: int): (big, int) · 62 unmodified lines
1101say(s: string)1008say(s: string)
1102{1009{
1103 if(dflag)1010 if(dflag)
1104 fprint(fildes(2), "%s\n", s);1011 sys->fprint(sys->fildes(2), "%s\n", s);
1105}1012}
appl/lib/venti.b+97−4
@@ -2,6 +2,7 @@ implement Venti; · 1 unmodified line
2 2
3include "sys.m";3include "sys.m";
4 sys: Sys;4 sys: Sys;
5 sprint: import sys;
5include "venti.m";6include "venti.m";
6 7
7BIT8SZ: con 1;8BIT8SZ: con 1;
@@ -566,7 +567,34 @@ gtstring(a: array of byte, o: int, n: int): string · 558 unmodified lines
566 break;567 break;
567 return string a[o:i];568 return string a[o:i];
568}569}
569unpackroot(d: array of byte): ref Root570
571Root.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
597Root.unpack(d: array of byte): ref Root
570{598{
571 if(len d != Rootsize){599 if(len d != Rootsize){
572 sys->werrstr("root entry is wrong length");600 sys->werrstr("root entry is wrong length");
@@ -587,11 +615,34 @@ unpackroot(d: array of byte): ref Root · 14 unmodified lines
587 o += Scoresize;615 o += Scoresize;
588 r.blocksize = g16(d, o);616 r.blocksize = g16(d, o);
589 o += BIT16SZ;617 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;
591 return r;621 return r;
592}622}
593 623
594unpackentry(d: array of byte): ref Entry624
625Entry.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
645Entry.unpack(d: array of byte): ref Entry
595{646{
596 if(len d != Entrysize){647 if(len d != Entrysize){
597 sys->werrstr("entry is wrong length");648 sys->werrstr("entry is wrong length");
@@ -606,7 +657,7 @@ unpackentry(d: array of byte): ref Entry · 8 unmodified lines
606 e.dsize = g16(d, i);657 e.dsize = g16(d, i);
607 i += BIT16SZ;658 i += BIT16SZ;
608 e.flags = int d[i];659 e.flags = int d[i];
609 e.depth= (e.flags & Entrydepthmask) >> Entrydepthshift;660 e.depth = (e.flags & Entrydepthmask) >> Entrydepthshift;
610 e.flags &= ~Entrydepthmask;661 e.flags &= ~Entrydepthmask;
611 i += BIT8SZ;662 i += BIT8SZ;
612 i += 5; # skip something...663 i += 5; # skip something...
@@ -662,3 +713,45 @@ g64(f: array of byte, i: int): big · 49 unmodified lines
662 b1 := (((((int f[i+4] << 8) | int f[i+5]) << 8) | int f[i+6]) << 8) | int f[i+7];713 b1 := (((((int f[i+4] << 8) | int f[i+5]) << 8) | int f[i+6]) << 8) | int f[i+7];
663 return (big b0 << 32) | (big b1 & 16rFFFFFFFF);714 return (big b0 << 32) | (big b1 & 16rFFFFFFFF);
664}715}
716
717p16(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
724p32(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
731p48(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
738ptstring(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
752pscore(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
15[15[
16.B -vd16.B -vd
17] [17] [
18.B -i
19|
20.B -x
21] [
18.B -a22.B -a
19.I addr23.I addr
20] [24] [
@@ -23,6 +27,10 @@ vacget, vacput \- venti archive utilities · 2 unmodified lines
23] [27] [
24.B -n28.B -n
25.I name29.I name
30] [
31.B -u uid
32] [
33.B -g gid
26]34]
27.I path ...35.I path ...
28.SH DESCRIPTION36.SH DESCRIPTION
@@ -62,14 +70,34 @@ bytes instead of the default 8192 byte blocks. Only for vacput. · 33 unmodified lines
62Use70Use
63.I name71.I name
64as the name in the root block. Only for vacput.72as the name in the root block. Only for vacput.
73.TP
74.BR -i " or " -x
75Read a list of files from stdin to include
76.RB ( -i )
77or exclude
78.RB ( -x )
79from the (recursively walked)
80.I paths
81specified on the command-line.
82Only for vacput.
83.TP
84.BI -u " uid"
85Use
86.I uid
87for all files.
88Only for vacput.
89.TP
90.BI -g " gid"
91Use
92.I gid
93for all files.
94Only for vacput.
65.SH SOURCE95.SH SOURCE
66.B /appl/cmd/vacget.b96.B /appl/cmd/vacget.b
67.br97.br
68.B /appl/cmd/vacput.b98.B /appl/cmd/vacput.b
69.SH SEE ALSO99.SH SEE ALSO
70.IR vcache (1),
71.IR venti (2),100.IR venti (2),
72.IR vacfs (4),101.IR vacfs (4)
73.IR ventisrv (8)
74.SH BUGS102.SH BUGS
75These tools need more testing.103These tools need more testing.
man/2/venti+3−7
@@ -8,8 +8,6 @@ venti := load Venti Venti->PATH; · 7 unmodified lines
8Session: import venti;8Session: import venti;
9 9
10init: fn();10init: fn();
11unpackentry: fn(d: array of byte): ref Entry;
12unpackroot: fn(d: array of byte): ref Root;
13 11
14Session: adt {12Session: adt {
15 new: fn(fd: ref Sys->FD): ref Session;13 new: fn(fd: ref Sys->FD): ref Session;
@@ -48,7 +46,7 @@ Blocks are additionally tagged with a · 32 unmodified lines
48facilitating recovery in the event of corruption.46facilitating recovery in the event of corruption.
49A47A
50.B Session48.B Session
51represents an session with a Venti server.49represents a session with a Venti server.
52.TP50.TP
53.IB s .new(\fIfd\fP)51.IB s .new(\fIfd\fP)
54.B New52.B New
@@ -99,9 +97,7 @@ contains the Venti score for the block that has been written. · 44 unmodified lines
99tells the Venti server to make sure that all data is committed to97tells the Venti server to make sure that all data is committed to
100active storage.98active storage.
101.SH SOURCE99.SH SOURCE
100.B /module/venti.m
101.br
102.B /appl/lib/venti.b102.B /appl/lib/venti.b
103.SH BUGS103.SH BUGS
104to do:
105Score adt
106entry packing/unpacking
107other Vmsgs, Session.rpc()?
module/vac.m+17−46
@@ -4,9 +4,6 @@ Vac: module { · 3 unmodified lines
4 4
5 dflag: int;5 dflag: int;
6 6
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
10 # mode bits7 # mode bits
11 Modeperm: con 8r777;8 Modeperm: con 8r777;
12 Modesticky,9 Modesticky,
@@ -24,45 +21,16 @@ Vac: module { · 11 unmodified lines
24 Modedev,21 Modedev,
25 Modenamedpipe: con 1<<(9+iota);22 Modenamedpipe: con 1<<(9+iota);
26 23
27 Entrysize: con 40;
28 Rootsize: con 300;
29 Metablocksize: con 12;24 Metablocksize: con 12;
30 Metaentrysize: con 4;25 Metaentrysize: con 4;
31 26
32 Dsize: con 8*1024;27 Dsize: con 8*1024;
33 28
34 Entryactive: con (1<<0); # entry is in use29 # DirPlan9, DirNT & DirGen not valid in version >= 9
35 Entrydir: con (1<<1); # a directory30 DirPlan9,
36 Entrydepthshift: con 2; # shift for pointer depth31 DirNT,
37 Entrydepthmask: con (16r7<<2); # mask for pointer depth32 DirQidspace,
38 Entrylocal: con (1<<5); # used for local storage: should not be set for venti blocks33 DirGen: con 1+iota;
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 };
66 34
67 Direntry: adt {35 Direntry: adt {
68 version: int;36 version: int;
@@ -72,6 +40,9 @@ Vac: module { · 3 unmodified lines
72 qid: big;40 qid: big;
73 uid, gid, mid: string;41 uid, gid, mid: string;
74 mtime, mcount, ctime, atime, mode, emode: int;42 mtime, mcount, ctime, atime, mode, emode: int;
43 qidspace: int;
44 qidoff: big;
45 qidmax: big;
75 46
76 new: fn(): ref Direntry;47 new: fn(): ref Direntry;
77 mk: fn(d: Sys->Dir): ref Direntry;48 mk: fn(d: Sys->Dir): ref Direntry;
@@ -115,7 +86,7 @@ Vac: module { · 37 unmodified lines
115 86
116 new: fn(s: ref Venti->Session, dtype, dsize: int): ref File;87 new: fn(s: ref Venti->Session, dtype, dsize: int): ref File;
117 write: fn(f: self ref File, d: array of byte): int;88 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;
119 };90 };
120 91
121 # for writing venti directories92 # for writing venti directories
@@ -125,8 +96,8 @@ Vac: module { · 3 unmodified lines
125 nd, ne: int;96 nd, ne: int;
126 97
127 new: fn(s: ref Venti->Session, dsize: int): ref Sink;98 new: fn(s: ref Venti->Session, dsize: int): ref Sink;
128 add: fn(m: self ref Sink, e: ref Entry): int;99 add: fn(m: self ref Sink, e: ref Venti->Entry): int;
129 finish: fn(m: self ref Sink): ref Entry;100 finish: fn(m: self ref Sink): ref Venti->Entry;
130 };101 };
131 102
132 Mentry: adt {103 Mentry: adt {
@@ -145,16 +116,16 @@ Vac: module { · 12 unmodified lines
145 116
146 new: fn(s: ref Venti->Session, dsize: int): ref MSink;117 new: fn(s: ref Venti->Session, dsize: int): ref MSink;
147 add: fn(m: self ref MSink, de: ref Direntry): int;118 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;
149 };120 };
150 121
151 # for reading pages from a hash tree referenced by an entry122 # for reading pages from a hash tree referenced by an entry
152 Source: adt {123 Source: adt {
153 session: ref Venti->Session;124 session: ref Venti->Session;
154 e: ref Entry;125 e: ref Venti->Entry;
155 dsize: int; # real dsize126 dsize: int; # real dsize
156 127
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;
158 get: fn(s: self ref Source, i: big, d: array of byte): int;129 get: fn(s: self ref Source, i: big, d: array of byte): int;
159 };130 };
160 131
@@ -164,7 +135,7 @@ Vac: module { · 3 unmodified lines
164 o: big;135 o: big;
165 136
166 mk: fn(s: ref Source): ref Vacfile;137 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;
168 read: fn(v: self ref Vacfile, d: array of byte, n: int): int;139 read: fn(v: self ref Vacfile, d: array of byte, n: int): int;
169 seek: fn(v: self ref Vacfile, offset: big): big;140 seek: fn(v: self ref Vacfile, offset: big): big;
170 pread: fn(v: self ref Vacfile, d: array of byte, n: int, offset: big): int;141 pread: fn(v: self ref Vacfile, d: array of byte, n: int, offset: big): int;
@@ -178,9 +149,9 @@ Vac: module { · 7 unmodified lines
178 i: int;149 i: int;
179 150
180 mk: fn(vf: ref Vacfile, ms: ref Source): ref Vacdir;151 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;
182 walk: fn(v: self ref Vacdir, elem: string): ref Direntry;153 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);
184 readdir: fn(v: self ref Vacdir): (int, ref Direntry);155 readdir: fn(v: self ref Vacdir): (int, ref Direntry);
185 rewind: fn(v: self ref Vacdir);156 rewind: fn(v: self ref Vacdir);
186 };157 };
module/venti.m+7−3
@@ -124,7 +124,10 @@ Venti: module { · 123 unmodified lines
124 rtype: string;124 rtype: string;
125 score: Venti->Score; # to a Dir block125 score: Venti->Score; # to a Dir block
126 blocksize: int; # maximum block size126 blocksize: int; # maximum block size
127 prev: Venti->Score; # last root block127 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;
128 };131 };
129 132
130 Entry: adt {133 Entry: adt {
@@ -135,6 +138,9 @@ Venti: module { · 4 unmodified lines
135 flags: int;138 flags: int;
136 size: big; # (XXX should be unsigned)139 size: big; # (XXX should be unsigned)
137 score: Venti->Score;140 score: Venti->Score;
141
142 pack: fn(e: self ref Entry): array of byte;
143 unpack: fn(d: array of byte): ref Entry;
138 };144 };
139 Score: adt {145 Score: adt {
140 a: array of byte;146 a: array of byte;
@@ -153,7 +159,5 @@ Venti: module { · 12 unmodified lines
153 sync: fn(s: self ref Session): int;159 sync: fn(s: self ref Session): int;
154 rpc: fn(s: self ref Session, m: ref Vmsg): (ref Vmsg, string);160 rpc: fn(s: self ref Session, m: ref Vmsg): (ref Vmsg, string);
155 };161 };
156 unpackentry: fn(d: array of byte): ref Entry;
157 unpackroot: fn(d: array of byte): ref Root;
158 init: fn();162 init: fn();
159};163};
opt/README+1−0
@@ -1 +1,2 @@
1optional components live in subdirectories of /opt.1optional components live in subdirectories of /opt.
2see opt(6) and opt(1)