| @@ -436,7 +436,7 @@ fflush(f: ref File, last: int): (int, ref Entry) · 435 unmodified lines |
| 436 | 436 | return (0, nil); |
| 437 | 437 | if(last && f.p[i].o == Scoresize) { |
| 438 | 438 | flags := Entryactive; |
| 439 | | − if(f.dtype & Dirtype) |
| 439 | + if(f.dtype == Dirtype) |
| 440 | 440 | flags |= Entrydir; |
| 441 | 441 | flags |= i<<Entrydepthshift; |
| 442 | 442 | score := Score(f.p[i].data()); |
| @@ -540,7 +540,7 @@ Mentry.cmp(a, b: ref Mentry): int · 97 unmodified lines |
| 540 | 540 | |
| 541 | 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 | 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 | 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 | 629 | power(b, e: int): big |
| @@ -640,13 +643,13 @@ blocksize(e: ref Entry): int · 13 unmodified lines |
| 640 | 643 | |
| 641 | 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; |
| 644 | | − if(i*big s.e.dsize >= s.e.size) |
| 646 | + npages := (s.e.size+big (s.dsize-1))/big s.dsize; |
| 647 | + if(i*big s.dsize >= s.e.size) |
| 645 | 648 | return 0; |
| 646 | 649 | |
| 647 | | − want := s.e.dsize; |
| 650 | + want := s.dsize; |
| 648 | 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 | 653 | last := s.e.score; |
| 651 | 654 | bsize := blocksize(s.e); |
| 652 | 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 | 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 | 718 | have := v.s.get(big (offset/big dsize), buf := array[dsize] of byte); |
| 715 | 719 | if(have <= 0) |
| 716 | 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 | 722 | o := int (offset % big dsize); |
| 719 | 723 | have -= o; |
| 720 | 724 | if(have > n) |
| @@ -775,7 +779,7 @@ finddirentry(d: array of byte, elem: string): (int, ref Direntry) · 54 unmodified lines |
| 775 | 779 | if(c == 0) |
| 776 | 780 | break; |
| 777 | 781 | } |
| 778 | | − de := readdirentry(d, left); |
| 782 | + de := readdirentry(d, left, 0); |
| 779 | 783 | if(de != nil && de.elem == elem) |
| 780 | 784 | return (1, de); |
| 781 | 785 | return (0, nil); |
| @@ -809,7 +813,7 @@ say(sprint("vfreadentry: reading entry=%d", entry)); · 27 unmodified lines |
| 809 | 813 | if(n < 0) |
| 810 | 814 | return nil; |
| 811 | 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 | 817 | return nil; |
| 814 | 818 | } |
| 815 | 819 | e := Entry.unpack(ebuf); |
| @@ -817,7 +821,8 @@ say(sprint("vfreadentry: reading entry=%d", entry)); · 1 unmodified line |
| 817 | 821 | werrstr("entry not active"); |
| 818 | 822 | return nil; |
| 819 | 823 | } |
| 820 | | − if(e.flags&Entrylocal) { |
| 824 | + # p9p writes archives with Entrylocal set? |
| 825 | + if(0 && e.flags&Entrylocal) { |
| 821 | 826 | werrstr("entry is local"); |
| 822 | 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 | 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 | 858 | me := Metaentry.unpack(buf, i); |
| 854 | 859 | if(me == nil) |
| 855 | 860 | return nil; |
| 856 | 861 | o := me.offset; |
| 857 | 862 | de := Direntry.unpack(buf[o:o+me.size]); |
| 858 | | − if(badelem(de.elem)) { |
| 863 | + if(badelem(de.elem) && !(allowroot && de.elem == "/")) { |
| 859 | 864 | werrstr(sprint("bad direntry: %s", de.elem)); |
| 860 | 865 | return nil; |
| 861 | 866 | } |
| @@ -875,18 +880,18 @@ badelem(elem: string): int · 13 unmodified lines |
| 875 | 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)); |
| 881 | | − dsize := vd.ms.e.dsize; |
| 885 | +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; |
| 882 | 887 | n := vd.ms.get(vd.p, buf := array[dsize] of byte); |
| 883 | 888 | if(n <= 0) |
| 884 | 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 | 891 | mb := Metablock.unpack(buf); |
| 887 | 892 | if(mb == nil) |
| 888 | 893 | return (-1, nil); |
| 889 | | − de := readdirentry(buf, vd.i); |
| 894 | + de := readdirentry(buf, vd.i, allowroot); |
| 890 | 895 | if(de == nil) |
| 891 | 896 | return (-1, nil); |
| 892 | 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 | 899 | vd.p++; |
| 895 | 900 | vd.i = 0; |
| 896 | 901 | } |
| 897 | | −say("vacdir.readdir: have entry"); |
| 902 | +say("vdreaddir: have entry"); |
| 898 | 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 | 912 | Vacdir.rewind(vd: self ref Vacdir) |
| 902 | 913 | { |
| 903 | 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 | 956 | say("top entries unpacked"); |
| 946 | 957 | |
| 947 | | − mroot := Vacdir.new(session, nil, e[2]); |
| 948 | | − (ok, de) := mroot.readdir(); |
| 958 | + mroot := Vacdir.mk(nil, Source.new(session, e[2])); |
| 959 | + (ok, de) := vdreaddir(mroot, 1); |
| 949 | 960 | if(ok <= 0) |
| 950 | 961 | return (nil, nil, sprint("reading root meta entry: %r")); |
| 951 | 962 | |