| @@ -436,7 +436,7 @@ fflush(f: ref File, last: int): (int, ref Entry) · 435 unmodified lines |
| 436 | return (0, nil); | 436 | return (0, nil); |
| 437 | if(last && f.p[i].o == Scoresize) { | 437 | if(last && f.p[i].o == Scoresize) { |
| 438 | flags := Entryactive; | 438 | flags := Entryactive; |
| 439 | if(f.dtype & Dirtype) | 439 | if(f.dtype == Dirtype) |
| 440 | flags |= Entrydir; | 440 | flags |= Entrydir; |
| 441 | flags |= i<<Entrydepthshift; | 441 | flags |= i<<Entrydepthshift; |
| 442 | score := Score(f.p[i].data()); | 442 | score := Score(f.p[i].data()); |
| @@ -540,7 +540,7 @@ Mentry.cmp(a, b: ref Mentry): int · 97 unmodified lines |
| 540 | | 540 | |
| 541 | MSink.new(s: ref Venti->Session, dsize: int): ref MSink | 541 | MSink.new(s: ref Venti->Session, dsize: int): ref MSink |
| 542 | { | 542 | { |
| 543 | return ref MSink(File.new(s, Dirtype, dsize), array[dsize] of byte, 0, nil); | 543 | return ref MSink(File.new(s, Datatype, dsize), array[dsize] of byte, 0, nil); |
| 544 | } | 544 | } |
| 545 | | 545 | |
| 546 | l2a[T](l: list of T): array of T | 546 | l2a[T](l: list of T): array of T |
| @@ -620,7 +620,10 @@ MSink.finish(m: self ref MSink): ref Entry · 73 unmodified lines |
| 620 | | 620 | |
| 621 | Source.new(s: ref Session, e: ref Entry): ref Source | 621 | Source.new(s: ref Session, e: ref Entry): ref Source |
| 622 | { | 622 | { |
| 623 | return ref Source(s, e); | 623 | dsize := e.dsize; |
| | 624 | if(e.flags&Entrydir) |
| | 625 | dsize = Entrysize*(dsize/Entrysize); |
| | 626 | return ref Source(s, e, dsize); |
| 624 | } | 627 | } |
| 625 | | 628 | |
| 626 | power(b, e: int): big | 629 | power(b, e: int): big |
| @@ -640,13 +643,13 @@ blocksize(e: ref Entry): int · 13 unmodified lines |
| 640 | | 643 | |
| 641 | Source.get(s: self ref Source, i: big, d: array of byte): int | 644 | Source.get(s: self ref Source, i: big, d: array of byte): int |
| 642 | { | 645 | { |
| 643 | npages := (s.e.size+big (s.e.dsize-1))/big s.e.dsize; | 646 | npages := (s.e.size+big (s.dsize-1))/big s.dsize; |
| 644 | if(i*big s.e.dsize >= s.e.size) | 647 | if(i*big s.dsize >= s.e.size) |
| 645 | return 0; | 648 | return 0; |
| 646 | | 649 | |
| 647 | want := s.e.dsize; | 650 | want := s.dsize; |
| 648 | if(i == npages-big 1) | 651 | if(i == npages-big 1) |
| 649 | want = int (s.e.size - i*big s.e.dsize); | 652 | want = int (s.e.size - i*big s.dsize); |
| 650 | last := s.e.score; | 653 | last := s.e.score; |
| 651 | bsize := blocksize(s.e); | 654 | bsize := blocksize(s.e); |
| 652 | buf: array of byte; | 655 | buf: array of byte; |
| @@ -710,11 +713,12 @@ Vacfile.read(v: self ref Vacfile, d: array of byte, n: int): int · 57 unmodified lines |
| 710 | | 713 | |
| 711 | Vacfile.pread(v: self ref Vacfile, d: array of byte, n: int, offset: big): int | 714 | Vacfile.pread(v: self ref Vacfile, d: array of byte, n: int, offset: big): int |
| 712 | { | 715 | { |
| 713 | dsize := v.s.e.dsize; | 716 | dsize := v.s.dsize; |
| | 717 | say(sprint("vf.preadn, len d %d, n %d, offset %bd", len d, n, offset)); |
| 714 | have := v.s.get(big (offset/big dsize), buf := array[dsize] of byte); | 718 | have := v.s.get(big (offset/big dsize), buf := array[dsize] of byte); |
| 715 | if(have <= 0) | 719 | if(have <= 0) |
| 716 | return have; | 720 | return have; |
| 717 | say(sprint("vacfile.read: have=%d dsize=%d", have, dsize)); | 721 | say(sprint("vacfile.pread: have=%d dsize=%d", have, dsize)); |
| 718 | o := int (offset % big dsize); | 722 | o := int (offset % big dsize); |
| 719 | have -= o; | 723 | have -= o; |
| 720 | if(have > n) | 724 | if(have > n) |
| @@ -775,7 +779,7 @@ finddirentry(d: array of byte, elem: string): (int, ref Direntry) · 54 unmodified lines |
| 775 | if(c == 0) | 779 | if(c == 0) |
| 776 | break; | 780 | break; |
| 777 | } | 781 | } |
| 778 | de := readdirentry(d, left); | 782 | de := readdirentry(d, left, 0); |
| 779 | if(de != nil && de.elem == elem) | 783 | if(de != nil && de.elem == elem) |
| 780 | return (1, de); | 784 | return (1, de); |
| 781 | return (0, nil); | 785 | return (0, nil); |
| @@ -809,7 +813,7 @@ say(sprint("vfreadentry: reading entry=%d", entry)); · 27 unmodified lines |
| 809 | if(n < 0) | 813 | if(n < 0) |
| 810 | return nil; | 814 | return nil; |
| 811 | if(n != len ebuf) { | 815 | if(n != len ebuf) { |
| 812 | werrstr(sprint("bad archive, entry=%d not present", entry)); | 816 | werrstr(sprint("bad archive, entry=%d not present (read %d, wanted %d)", entry, n, len ebuf)); |
| 813 | return nil; | 817 | return nil; |
| 814 | } | 818 | } |
| 815 | e := Entry.unpack(ebuf); | 819 | e := Entry.unpack(ebuf); |
| @@ -817,7 +821,8 @@ say(sprint("vfreadentry: reading entry=%d", entry)); · 1 unmodified line |
| 817 | werrstr("entry not active"); | 821 | werrstr("entry not active"); |
| 818 | return nil; | 822 | return nil; |
| 819 | } | 823 | } |
| 820 | if(e.flags&Entrylocal) { | 824 | # p9p writes archives with Entrylocal set? |
| | 825 | if(0 && e.flags&Entrylocal) { |
| 821 | werrstr("entry is local"); | 826 | werrstr("entry is local"); |
| 822 | return nil; | 827 | return nil; |
| 823 | } | 828 | } |
| @@ -848,14 +853,14 @@ say(sprint("vacdir.open: have mentry, score=%s size=%bd", me.score.text(), e.siz · 24 unmodified lines |
| 848 | return (e, me); | 853 | return (e, me); |
| 849 | } | 854 | } |
| 850 | | 855 | |
| 851 | readdirentry(buf: array of byte, i: int): ref Direntry | 856 | readdirentry(buf: array of byte, i: int, allowroot: int): ref Direntry |
| 852 | { | 857 | { |
| 853 | me := Metaentry.unpack(buf, i); | 858 | me := Metaentry.unpack(buf, i); |
| 854 | if(me == nil) | 859 | if(me == nil) |
| 855 | return nil; | 860 | return nil; |
| 856 | o := me.offset; | 861 | o := me.offset; |
| 857 | de := Direntry.unpack(buf[o:o+me.size]); | 862 | de := Direntry.unpack(buf[o:o+me.size]); |
| 858 | if(badelem(de.elem)) { | 863 | if(badelem(de.elem) && !(allowroot && de.elem == "/")) { |
| 859 | werrstr(sprint("bad direntry: %s", de.elem)); | 864 | werrstr(sprint("bad direntry: %s", de.elem)); |
| 860 | return nil; | 865 | return nil; |
| 861 | } | 866 | } |
| @@ -875,18 +880,18 @@ badelem(elem: string): int · 13 unmodified lines |
| 875 | return elem == "" || elem == "." || elem == ".." || has('/', elem) || has(0, elem); | 880 | return elem == "" || elem == "." || elem == ".." || has('/', elem) || has(0, elem); |
| 876 | } | 881 | } |
| 877 | | 882 | |
| 878 | Vacdir.readdir(vd: self ref Vacdir): (int, ref Direntry) | 883 | vdreaddir(vd: ref Vacdir, allowroot: int): (int, ref Direntry) |
| 879 | { | 884 | { |
| 880 | say(sprint("vacdir.readdir: ms.e.size=%bd vd.p=%bd vd.i=%d", vd.ms.e.size, vd.p, vd.i)); | 885 | say(sprint("vdreaddir: ms.e.size=%bd vd.p=%bd vd.i=%d", vd.ms.e.size, vd.p, vd.i)); |
| 881 | dsize := vd.ms.e.dsize; | 886 | dsize := vd.ms.dsize; |
| 882 | n := vd.ms.get(vd.p, buf := array[dsize] of byte); | 887 | n := vd.ms.get(vd.p, buf := array[dsize] of byte); |
| 883 | if(n <= 0) | 888 | if(n <= 0) |
| 884 | return (n, nil); | 889 | return (n, nil); |
| 885 | say(sprint("vacdir.readdir: have buf, length=%d e.size=%bd", n, vd.ms.e.size)); | 890 | say(sprint("vdreaddir: have buf, length=%d e.size=%bd", n, vd.ms.e.size)); |
| 886 | mb := Metablock.unpack(buf); | 891 | mb := Metablock.unpack(buf); |
| 887 | if(mb == nil) | 892 | if(mb == nil) |
| 888 | return (-1, nil); | 893 | return (-1, nil); |
| 889 | de := readdirentry(buf, vd.i); | 894 | de := readdirentry(buf, vd.i, allowroot); |
| 890 | if(de == nil) | 895 | if(de == nil) |
| 891 | return (-1, nil); | 896 | return (-1, nil); |
| 892 | vd.i++; | 897 | vd.i++; |
| @@ -894,10 +899,16 @@ say(sprint("vacdir.readdir: have buf, length=%d e.size=%bd", n, vd.ms.e.size)); · 1 unmodified line |
| 894 | vd.p++; | 899 | vd.p++; |
| 895 | vd.i = 0; | 900 | vd.i = 0; |
| 896 | } | 901 | } |
| 897 | say("vacdir.readdir: have entry"); | 902 | say("vdreaddir: have entry"); |
| 898 | return (1, de); | 903 | return (1, de); |
| 899 | } | 904 | } |
| 900 | | 905 | |
| | 906 | Vacdir.readdir(vd: self ref Vacdir): (int, ref Direntry) |
| | 907 | { |
| | 908 | return vdreaddir(vd, 0); |
| | 909 | } |
| | 910 | |
| | 911 | |
| 901 | Vacdir.rewind(vd: self ref Vacdir) | 912 | Vacdir.rewind(vd: self ref Vacdir) |
| 902 | { | 913 | { |
| 903 | vd.p = big 0; | 914 | vd.p = big 0; |
| @@ -944,8 +955,8 @@ vdroot(session: ref Session, score: Venti->Score): (ref Vacdir, ref Direntry, st · 40 unmodified lines |
| 944 | } | 955 | } |
| 945 | say("top entries unpacked"); | 956 | say("top entries unpacked"); |
| 946 | | 957 | |
| 947 | mroot := Vacdir.new(session, nil, e[2]); | 958 | mroot := Vacdir.mk(nil, Source.new(session, e[2])); |
| 948 | (ok, de) := mroot.readdir(); | 959 | (ok, de) := vdreaddir(mroot, 1); |
| 949 | if(ok <= 0) | 960 | if(ok <= 0) |
| 950 | return (nil, nil, sprint("reading root meta entry: %r")); | 961 | return (nil, nil, sprint("reading root meta entry: %r")); |
| 951 | | 962 | |