diff options
| author | Charles.Forsyth <devnull@localhost> | 2009-05-21 20:02:52 +0000 |
|---|---|---|
| committer | Charles.Forsyth <devnull@localhost> | 2009-05-21 20:02:52 +0000 |
| commit | 04b29c1c92c3b38bc33bb1777400d00c0e2681a0 (patch) | |
| tree | 576eacf430d86eebe3c4f396a57525c03dabec16 /appl/lib | |
| parent | af1b61f55a195350b4491438e8b2c381c4ba34bc (diff) | |
20090521-2101
Diffstat (limited to 'appl/lib')
| -rw-r--r-- | appl/lib/vac.b | 55 |
1 files changed, 33 insertions, 22 deletions
diff --git a/appl/lib/vac.b b/appl/lib/vac.b index 53967661..0284fb1a 100644 --- a/appl/lib/vac.b +++ b/appl/lib/vac.b @@ -436,7 +436,7 @@ fflush(f: ref File, last: int): (int, ref Entry) return (0, nil); if(last && f.p[i].o == Scoresize) { flags := Entryactive; - if(f.dtype & Dirtype) + if(f.dtype == Dirtype) flags |= Entrydir; flags |= i<<Entrydepthshift; score := Score(f.p[i].data()); @@ -540,7 +540,7 @@ Mentry.cmp(a, b: ref Mentry): int MSink.new(s: ref Venti->Session, dsize: int): ref MSink { - return ref MSink(File.new(s, Dirtype, dsize), array[dsize] of byte, 0, nil); + return ref MSink(File.new(s, Datatype, dsize), array[dsize] of byte, 0, nil); } l2a[T](l: list of T): array of T @@ -620,7 +620,10 @@ MSink.finish(m: self ref MSink): ref Entry Source.new(s: ref Session, e: ref Entry): ref Source { - return ref Source(s, e); + dsize := e.dsize; + if(e.flags&Entrydir) + dsize = Entrysize*(dsize/Entrysize); + return ref Source(s, e, dsize); } power(b, e: int): big @@ -640,13 +643,13 @@ blocksize(e: ref Entry): int Source.get(s: self ref Source, i: big, d: array of byte): int { - npages := (s.e.size+big (s.e.dsize-1))/big s.e.dsize; - if(i*big s.e.dsize >= s.e.size) + npages := (s.e.size+big (s.dsize-1))/big s.dsize; + if(i*big s.dsize >= s.e.size) return 0; - want := s.e.dsize; + want := s.dsize; if(i == npages-big 1) - want = int (s.e.size - i*big s.e.dsize); + want = int (s.e.size - i*big s.dsize); last := s.e.score; bsize := blocksize(s.e); buf: array of byte; @@ -710,11 +713,12 @@ Vacfile.read(v: self ref Vacfile, d: array of byte, n: int): int Vacfile.pread(v: self ref Vacfile, d: array of byte, n: int, offset: big): int { - dsize := v.s.e.dsize; + dsize := v.s.dsize; +say(sprint("vf.preadn, len d %d, n %d, offset %bd", len d, n, offset)); have := v.s.get(big (offset/big dsize), buf := array[dsize] of byte); if(have <= 0) return have; -say(sprint("vacfile.read: have=%d dsize=%d", have, dsize)); +say(sprint("vacfile.pread: have=%d dsize=%d", have, dsize)); o := int (offset % big dsize); have -= o; if(have > n) @@ -775,7 +779,7 @@ finddirentry(d: array of byte, elem: string): (int, ref Direntry) if(c == 0) break; } - de := readdirentry(d, left); + de := readdirentry(d, left, 0); if(de != nil && de.elem == elem) return (1, de); return (0, nil); @@ -809,7 +813,7 @@ say(sprint("vfreadentry: reading entry=%d", entry)); if(n < 0) return nil; if(n != len ebuf) { - werrstr(sprint("bad archive, entry=%d not present", entry)); + werrstr(sprint("bad archive, entry=%d not present (read %d, wanted %d)", entry, n, len ebuf)); return nil; } e := Entry.unpack(ebuf); @@ -817,7 +821,8 @@ say(sprint("vfreadentry: reading entry=%d", entry)); werrstr("entry not active"); return nil; } - if(e.flags&Entrylocal) { + # p9p writes archives with Entrylocal set? + if(0 && e.flags&Entrylocal) { werrstr("entry is local"); return nil; } @@ -848,14 +853,14 @@ say(sprint("vacdir.open: have mentry, score=%s size=%bd", me.score.text(), e.siz return (e, me); } -readdirentry(buf: array of byte, i: int): ref Direntry +readdirentry(buf: array of byte, i: int, allowroot: int): ref Direntry { me := Metaentry.unpack(buf, i); if(me == nil) return nil; o := me.offset; de := Direntry.unpack(buf[o:o+me.size]); - if(badelem(de.elem)) { + if(badelem(de.elem) && !(allowroot && de.elem == "/")) { werrstr(sprint("bad direntry: %s", de.elem)); return nil; } @@ -875,18 +880,18 @@ badelem(elem: string): int return elem == "" || elem == "." || elem == ".." || has('/', elem) || has(0, elem); } -Vacdir.readdir(vd: self ref Vacdir): (int, ref Direntry) +vdreaddir(vd: ref Vacdir, allowroot: int): (int, ref Direntry) { -say(sprint("vacdir.readdir: ms.e.size=%bd vd.p=%bd vd.i=%d", vd.ms.e.size, vd.p, vd.i)); - dsize := vd.ms.e.dsize; +say(sprint("vdreaddir: ms.e.size=%bd vd.p=%bd vd.i=%d", vd.ms.e.size, vd.p, vd.i)); + dsize := vd.ms.dsize; n := vd.ms.get(vd.p, buf := array[dsize] of byte); if(n <= 0) return (n, nil); -say(sprint("vacdir.readdir: have buf, length=%d e.size=%bd", n, vd.ms.e.size)); +say(sprint("vdreaddir: have buf, length=%d e.size=%bd", n, vd.ms.e.size)); mb := Metablock.unpack(buf); if(mb == nil) return (-1, nil); - de := readdirentry(buf, vd.i); + de := readdirentry(buf, vd.i, allowroot); if(de == nil) return (-1, nil); vd.i++; @@ -894,10 +899,16 @@ say(sprint("vacdir.readdir: have buf, length=%d e.size=%bd", n, vd.ms.e.size)); vd.p++; vd.i = 0; } -say("vacdir.readdir: have entry"); +say("vdreaddir: have entry"); return (1, de); } +Vacdir.readdir(vd: self ref Vacdir): (int, ref Direntry) +{ + return vdreaddir(vd, 0); +} + + Vacdir.rewind(vd: self ref Vacdir) { vd.p = big 0; @@ -944,8 +955,8 @@ vdroot(session: ref Session, score: Venti->Score): (ref Vacdir, ref Direntry, st } say("top entries unpacked"); - mroot := Vacdir.new(session, nil, e[2]); - (ok, de) := mroot.readdir(); + mroot := Vacdir.mk(nil, Source.new(session, e[2])); + (ok, de) := vdreaddir(mroot, 1); if(ok <= 0) return (nil, nil, sprint("reading root meta entry: %r")); |
