Unified · Split
| @@ -1,3 +1,5 @@ | |||
| 1 | 20110516 | ||
| 2 | merge changes from vac branch of mechiel-inferno-os (googlecode) | ||
| 1 | 20110426 | 3 | 20110426 |
| 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] |
| 3 | 20110419 | 5 | 20110419 |
| @@ -2,35 +2,36 @@ implement Vacfs; · 1 unmodified line | |||
| 2 | 2 | ||
| 3 | include "sys.m"; | 3 | include "sys.m"; |
| 4 | sys: Sys; | 4 | sys: Sys; |
| 5 | sprint: import sys; | ||
| 5 | include "draw.m"; | 6 | include "draw.m"; |
| 6 | include "arg.m"; | 7 | include "arg.m"; |
| 8 | include "dial.m"; | ||
| 9 | dial: Dial; | ||
| 7 | include "string.m"; | 10 | include "string.m"; |
| 11 | str: String; | ||
| 8 | include "daytime.m"; | 12 | include "daytime.m"; |
| 13 | dt: Daytime; | ||
| 9 | include "venti.m"; | 14 | include "venti.m"; |
| 15 | venti: Venti; | ||
| 16 | Root, Entry, Score, Session: import venti; | ||
| 17 | Roottype, Dirtype, Pointertype0, Datatype: import venti; | ||
| 10 | include "vac.m"; | 18 | include "vac.m"; |
| 19 | vac: Vac; | ||
| 20 | Direntry, Vacdir, Vacfile: import vac; | ||
| 11 | include "styx.m"; | 21 | include "styx.m"; |
| 12 | styx: Styx; | 22 | styx: Styx; |
| 13 | Tmsg, Rmsg: import styx; | 23 | Tmsg, Rmsg: import styx; |
| 14 | include "styxservers.m"; | 24 | include "styxservers.m"; |
| 15 | 25 | styxservers: Styxservers; | |
| 16 | str: String; | 26 | Styxserver, Fid, Navigator, Navop, Enotfound: import styxservers; |
| 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; | ||
| 27 | 27 | ||
| 28 | Vacfs: module { | 28 | Vacfs: 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 | ||
| 32 | addr := "net!$venti!venti"; | 32 | addr := "$venti"; |
| 33 | dflag := pflag := 0; | 33 | dflag: int; |
| 34 | pflag: int; | ||
| 34 | session: ref Session; | 35 | session: ref Session; |
| 35 | 36 | ||
| 36 | ss: ref Styxserver; | 37 | ss: 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 | |||
| 353 | loop: | 358 | loop: |
| 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 | ||
| 424 | user(): string | 429 | user(): string |
| 425 | { | 430 | { |
| 426 | if((fd := sys->open("/dev/user", Sys->OREAD)) != nil | 431 | 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 | ||
| 432 | error(s: string) | 438 | pid(): 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 | ||
| 439 | warn(s: string) | 443 | killgrp(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 | ||
| 444 | say(s: string) | 448 | say(s: string) |
| @@ -447,9 +451,17 @@ say(s: string) · 2 unmodified lines | |||
| 447 | warn(s); | 451 | warn(s); |
| 448 | } | 452 | } |
| 449 | 453 | ||
| 450 | killgrp() | 454 | fd2: ref Sys->FD; |
| 455 | warn(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 | |||
| 462 | fail(s: string) | ||
| 463 | { | ||
| 464 | warn(s); | ||
| 465 | killgrp(pid()); | ||
| 466 | raise "fail:"+s; | ||
| 455 | } | 467 | } |
| @@ -2,30 +2,33 @@ implement Vacget; · 1 unmodified line | |||
| 2 | 2 | ||
| 3 | include "sys.m"; | 3 | include "sys.m"; |
| 4 | sys: Sys; | 4 | sys: Sys; |
| 5 | sprint: import sys; | ||
| 5 | include "draw.m"; | 6 | include "draw.m"; |
| 6 | include "bufio.m"; | 7 | include "bufio.m"; |
| 7 | bufio: Bufio; | 8 | bufio: Bufio; |
| 8 | Iobuf: import bufio; | 9 | Iobuf: import bufio; |
| 9 | include "arg.m"; | 10 | include "arg.m"; |
| 11 | include "dial.m"; | ||
| 12 | dial: Dial; | ||
| 10 | include "string.m"; | 13 | include "string.m"; |
| 14 | str: String; | ||
| 11 | include "venti.m"; | 15 | include "venti.m"; |
| 16 | venti: Venti; | ||
| 17 | Root, Entry, Score, Session: import venti; | ||
| 12 | include "vac.m"; | 18 | include "vac.m"; |
| 13 | 19 | vac: Vac; | |
| 14 | str: String; | 20 | Direntry, Vacdir, Vacfile: import vac; |
| 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; | ||
| 22 | 21 | ||
| 23 | Vacget: module { | 22 | Vacget: 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 | ||
| 27 | addr := "net!$venti!venti"; | 26 | addr := "$venti"; |
| 28 | dflag := vflag := pflag := tflag := 0; | 27 | dflag: int; |
| 28 | vflag: int; | ||
| 29 | pflag: int; | ||
| 30 | tflag: int; | ||
| 31 | |||
| 29 | session: ref Session; | 32 | session: ref Session; |
| 30 | 33 | ||
| 31 | init(nil: ref Draw->Context, args: list of string) | 34 | 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 | |||
| 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 | ||
| 184 | error(s: string) | 187 | say(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 | ||
| 193 | fd2: ref Sys->FD; | ||
| 190 | warn(s: string) | 194 | warn(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 | ||
| 195 | say(s: string) | 201 | fail(s: string) |
| 196 | { | 202 | { |
| 197 | if(dflag) | 203 | warn(s); |
| 198 | warn(s); | 204 | raise "fail:"+s; |
| 199 | } | 205 | } |
| @@ -2,81 +2,113 @@ implement Vacput; · 1 unmodified line | |||
| 2 | 2 | ||
| 3 | include "sys.m"; | 3 | include "sys.m"; |
| 4 | sys: Sys; | 4 | sys: Sys; |
| 5 | sprint: import sys; | ||
| 5 | include "draw.m"; | 6 | include "draw.m"; |
| 7 | include "arg.m"; | ||
| 6 | include "daytime.m"; | 8 | include "daytime.m"; |
| 9 | dt: Daytime; | ||
| 7 | include "bufio.m"; | 10 | include "bufio.m"; |
| 8 | bufio: Bufio; | 11 | bufio: Bufio; |
| 9 | Iobuf: import bufio; | 12 | Iobuf: import bufio; |
| 10 | include "arg.m"; | 13 | include "dial.m"; |
| 14 | dial: Dial; | ||
| 11 | include "string.m"; | 15 | include "string.m"; |
| 16 | str: String; | ||
| 17 | include "tables.m"; | ||
| 18 | tables: Tables; | ||
| 19 | Strhash: import tables; | ||
| 12 | include "venti.m"; | 20 | include "venti.m"; |
| 21 | venti: Venti; | ||
| 22 | Root, Entry, Score, Session: import venti; | ||
| 13 | include "vac.m"; | 23 | include "vac.m"; |
| 14 | 24 | vac: Vac; | |
| 15 | daytime: Daytime; | 25 | Direntry, File, Sink, MSink: import vac; |
| 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 | 26 | ||
| 25 | Vacput: module { | 27 | Vacput: 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 | ||
| 29 | addr := "net!$venti!venti"; | 31 | addr := "$venti"; |
| 30 | dflag := 0; | 32 | dflag: int; |
| 31 | vflag := 0; | 33 | iflag: int; |
| 34 | vflag: int; | ||
| 35 | xflag: int; | ||
| 32 | blocksize := vac->Dsize; | 36 | blocksize := vac->Dsize; |
| 37 | uid: string; | ||
| 38 | gid: string; | ||
| 39 | |||
| 40 | pathgen: big; | ||
| 41 | |||
| 42 | bout: ref Iobuf; | ||
| 33 | session: ref Session; | 43 | session: ref Session; |
| 34 | name := "vac"; | 44 | name := "vac"; |
| 45 | itab, | ||
| 46 | xtab: ref Strhash[string]; # include/exclude paths | ||
| 35 | 47 | ||
| 36 | init(nil: ref Draw->Context, args: list of string) | 48 | init(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 | |||
| 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; | ||
| 130 | } | 196 | } |
| 131 | 197 | ||
| 132 | writepath(path: string, s: ref Sink, ms: ref MSink) | 198 | writepath(path: string, s: ref Sink, ms: ref MSink) |
| 133 | { | 199 | { |
| 134 | if(vflag) | 200 | if(!usepath(path)) |
| 135 | print("%s\n", path); | 201 | return; |
| 136 | say("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)); |
| 143 | say("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) { |
| 156 | say("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 { |
| 178 | say("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 | } |
| 183 | say("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); |
| 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; | ||
| 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")); |
| 201 | say("writepath done"); | ||
| 202 | } | 271 | } |
| 203 | 272 | ||
| 204 | writefile(path: string, fd: ref Sys->FD): ref Entry | 273 | writefile(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 | ||
| 235 | user(): string | 302 | user(): string |
| 236 | { | 303 | { |
| 237 | if((fd := sys->open("/dev/user", Sys->OREAD)) != nil | 304 | 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 | ||
| 243 | error(s: string) | 311 | fd2: ref Sys->FD; |
| 244 | { | ||
| 245 | warn(s); | ||
| 246 | raise "fail:"+s; | ||
| 247 | } | ||
| 248 | |||
| 249 | warn(s: string) | 312 | warn(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 | ||
| 254 | say(s: string) | 319 | say(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 | |||
| 325 | fail(s: string) | ||
| 326 | { | ||
| 327 | warn(s); | ||
| 328 | raise "fail:"+s; | ||
| 329 | } | ||
| @@ -1,19 +1,17 @@ | |||
| 1 | implement Vac; | 1 | implement Vac; |
| 2 | 2 | ||
| 3 | include "sys.m"; | 3 | include "sys.m"; |
| 4 | sys: Sys; | ||
| 5 | sprint: import sys; | ||
| 4 | include "venti.m"; | 6 | include "venti.m"; |
| 7 | venti: Venti; | ||
| 8 | Entrysize, Scoresize, Roottype, Dirtype, Pointertype0, Datatype: import venti; | ||
| 9 | Root, Entry, Score, Session: import venti; | ||
| 5 | include "vac.m"; | 10 | include "vac.m"; |
| 6 | 11 | ||
| 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; | ||
| 13 | 12 | ||
| 14 | dflag = 0; | 13 | dflag = 0; |
| 15 | 14 | ||
| 16 | # from venti.b | ||
| 17 | BIT8SZ: con 1; | 15 | BIT8SZ: con 1; |
| 18 | BIT16SZ: con 2; | 16 | BIT16SZ: con 2; |
| 19 | BIT32SZ: con 4; | 17 | BIT32SZ: con 4; |
| @@ -32,7 +30,6 @@ blankdirentry: Direntry; · 12 unmodified lines | |||
| 32 | blankmetablock: Metablock; | 30 | blankmetablock: Metablock; |
| 33 | blankmetaentry: Metaentry; | 31 | blankmetaentry: Metaentry; |
| 34 | 32 | ||
| 35 | |||
| 36 | init() | 33 | init() |
| 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 | ||
| 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 | |||
| 192 | Direntry.new(): ref Direntry | 40 | Direntry.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 | ||
| 197 | Direntry.mk(d: Sys->Dir): ref Direntry | 45 | Direntry.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 | ||
| 212 | Direntry.mkdir(de: self ref Direntry): ref Sys->Dir | 60 | Direntry.mkdir(de: self ref Direntry): ref Sys->Dir |
| @@ -233,8 +81,14 @@ strlen(s: string): int · 20 unmodified lines | |||
| 233 | 81 | ||
| 234 | Direntry.pack(de: self ref Direntry): array of byte | 82 | Direntry.pack(de: self ref Direntry): array of byte |
| 235 | { | 83 | { |
| 236 | # assume version 9 | 84 | 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 here | 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 | } | ||
| 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 | |||
| 340 | Metablock.unpack(d: array of byte): ref Metablock | 216 | Metablock.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; |
| 604 | say(sprint("msink: adding direntry, length %d", len d)); | 480 | if(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 | |||
| 621 | Source.new(s: ref Session, e: ref Entry): ref Source | 497 | Source.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 | |||
| 714 | Vacfile.pread(v: self ref Vacfile, d: array of byte, n: int, offset: big): int | 590 | Vacfile.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; |
| 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)); |
| 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; |
| 721 | say(sprint("vacfile.pread: have=%d dsize=%d", have, dsize)); | 597 | if(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 | ||
| 808 | vfreadentry(vf: ref Vacfile, entry: int): ref Entry | 684 | vfreadentry(vf: ref Vacfile, entry: int): ref Entry |
| 809 | { | 685 | { |
| 810 | say(sprint("vfreadentry: reading entry=%d", entry)); | 686 | if(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 | } |
| 829 | say(sprint("vreadentry: have entry, score=%s", e.score.text())); | 707 | if(dflag) say(sprint("vreadentry: have entry, score=%s", e.score.text())); |
| 830 | return e; | 708 | return e; |
| 831 | } | 709 | } |
| 832 | 710 | ||
| 833 | Vacdir.open(vd: self ref Vacdir, de: ref Direntry): (ref Entry, ref Entry) | 711 | Vacdir.open(vd: self ref Vacdir, de: ref Direntry): (ref Entry, ref Entry) |
| 834 | { | 712 | { |
| 835 | say(sprint("vacdir.open: opening entry=%d", de.entry)); | 713 | if(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 | } |
| 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)); |
| 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); |
| 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)); |
| 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 | ||
| 883 | vdreaddir(vd: ref Vacdir, allowroot: int): (int, ref Direntry) | 763 | vdreaddir(vd: ref Vacdir, allowroot: int): (int, ref Direntry) |
| 884 | { | 764 | { |
| 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)); |
| 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); |
| 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)); |
| 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 | } |
| 902 | say("vdreaddir: have entry"); | 782 | if(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 | ||
| 919 | vdroot(session: ref Session, score: Venti->Score): (ref Vacdir, ref Direntry, string) | 799 | vdroot(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 score | 813 | 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"); | 832 | if(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 | ||
| 963 | say(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 | |||
| 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 | |||
| 977 | gscore(f: array of byte, i: int): Score | 878 | gscore(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 | ||
| 994 | g48(f: array of byte, i: int): big | 895 | g48(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 | ||
| 1001 | g64(f: array of byte, i: int): big | 900 | g64(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 | ||
| 1008 | p16(d: array of byte, i: int, v: int): int | 905 | 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 | |||
| 1033 | return i+BIT64SZ; | 930 | return i+BIT64SZ; |
| 1034 | } | 931 | } |
| 1035 | 932 | ||
| 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 | |||
| 1036 | ptstring(d: array of byte, i: int, s: string, l: int): int | 943 | ptstring(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 | |||
| 1101 | say(s: string) | 1008 | say(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 | } |
| @@ -2,6 +2,7 @@ implement Venti; · 1 unmodified line | |||
| 2 | 2 | ||
| 3 | include "sys.m"; | 3 | include "sys.m"; |
| 4 | sys: Sys; | 4 | sys: Sys; |
| 5 | sprint: import sys; | ||
| 5 | include "venti.m"; | 6 | include "venti.m"; |
| 6 | 7 | ||
| 7 | BIT8SZ: con 1; | 8 | BIT8SZ: 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 | } |
| 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 | ||
| 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 | ||
| 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 | ||
| 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 | |||
| 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 | } | ||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
| @@ -1 +1 @@ | |||
| 1 | #define VERSION "Fourth Edition (20110426)" | 1 | #define VERSION "Fourth Edition (20110516)" |
| @@ -15,6 +15,10 @@ vacget, vacput \- venti archive utilities · 14 unmodified lines | |||
| 15 | [ | 15 | [ |
| 16 | .B -vd | 16 | .B -vd |
| 17 | ] [ | 17 | ] [ |
| 18 | .B -i | ||
| 19 | | | ||
| 20 | .B -x | ||
| 21 | ] [ | ||
| 18 | .B -a | 22 | .B -a |
| 19 | .I addr | 23 | .I addr |
| 20 | ] [ | 24 | ] [ |
| @@ -23,6 +27,10 @@ vacget, vacput \- venti archive utilities · 2 unmodified lines | |||
| 23 | ] [ | 27 | ] [ |
| 24 | .B -n | 28 | .B -n |
| 25 | .I name | 29 | .I name |
| 30 | ] [ | ||
| 31 | .B -u uid | ||
| 32 | ] [ | ||
| 33 | .B -g gid | ||
| 26 | ] | 34 | ] |
| 27 | .I path ... | 35 | .I path ... |
| 28 | .SH DESCRIPTION | 36 | .SH DESCRIPTION |
| @@ -62,14 +70,34 @@ bytes instead of the default 8192 byte blocks. Only for vacput. · 33 unmodified lines | |||
| 62 | Use | 70 | Use |
| 63 | .I name | 71 | .I name |
| 64 | as the name in the root block. Only for vacput. | 72 | 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. | ||
| 65 | .SH SOURCE | 95 | .SH SOURCE |
| 66 | .B /appl/cmd/vacget.b | 96 | .B /appl/cmd/vacget.b |
| 67 | .br | 97 | .br |
| 68 | .B /appl/cmd/vacput.b | 98 | .B /appl/cmd/vacput.b |
| 69 | .SH SEE ALSO | 99 | .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 BUGS | 102 | .SH BUGS |
| 75 | These tools need more testing. | 103 | These tools need more testing. |
| @@ -8,8 +8,6 @@ venti := load Venti Venti->PATH; · 7 unmodified lines | |||
| 8 | Session: import venti; | 8 | Session: import venti; |
| 9 | 9 | ||
| 10 | init: fn(); | 10 | init: fn(); |
| 11 | unpackentry: fn(d: array of byte): ref Entry; | ||
| 12 | unpackroot: fn(d: array of byte): ref Root; | ||
| 13 | 11 | ||
| 14 | Session: adt { | 12 | Session: 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 | |||
| 48 | facilitating recovery in the event of corruption. | 46 | facilitating recovery in the event of corruption. |
| 49 | A | 47 | A |
| 50 | .B Session | 48 | .B Session |
| 51 | represents an session with a Venti server. | 49 | represents a session with a Venti server. |
| 52 | .TP | 50 | .TP |
| 53 | .IB s .new(\fIfd\fP) | 51 | .IB s .new(\fIfd\fP) |
| 54 | .B New | 52 | .B New |
| @@ -99,9 +97,7 @@ contains the Venti score for the block that has been written. · 44 unmodified lines | |||
| 99 | tells the Venti server to make sure that all data is committed to | 97 | tells the Venti server to make sure that all data is committed to |
| 100 | active storage. | 98 | active storage. |
| 101 | .SH SOURCE | 99 | .SH SOURCE |
| 100 | .B /module/venti.m | ||
| 101 | .br | ||
| 102 | .B /appl/lib/venti.b | 102 | .B /appl/lib/venti.b |
| 103 | .SH BUGS | 103 | .SH BUGS |
| 104 | to do: | ||
| 105 | Score adt | ||
| 106 | entry packing/unpacking | ||
| 107 | other Vmsgs, Session.rpc()? | ||
| @@ -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 bits | 7 | # 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 use | 29 | # DirPlan9, DirNT & DirGen not valid in version >= 9 |
| 35 | Entrydir: con (1<<1); # a directory | 30 | DirPlan9, |
| 36 | Entrydepthshift: con 2; # shift for pointer depth | 31 | DirNT, |
| 37 | Entrydepthmask: con (16r7<<2); # mask for pointer depth | 32 | DirQidspace, |
| 38 | Entrylocal: con (1<<5); # used for local storage: should not be set for venti blocks | 33 | 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 directories | 92 | # 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 entry | 122 | # 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 dsize | 126 | 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 | }; |
| @@ -124,7 +124,10 @@ Venti: module { · 123 unmodified lines | |||
| 124 | rtype: string; | 124 | rtype: string; |
| 125 | score: Venti->Score; # to a Dir block | 125 | score: Venti->Score; # to a Dir block |
| 126 | blocksize: int; # maximum block size | 126 | 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; | ||
| 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 | }; |
| @@ -1 +1,2 @@ | |||
| 1 | optional components live in subdirectories of /opt. | 1 | optional components live in subdirectories of /opt. |
| 2 | see opt(6) and opt(1) | ||