| ... | @@ -109,6 +109,10 @@ pub const Header = struct { | ... | @@ -109,6 +109,10 @@ pub const Header = struct { |
| 109 | return header.str(0, 100); | 109 | return header.str(0, 100); |
| 110 | } | 110 | } |
| 111 | | 111 | |
| | 112 | pub fn mode(header: Header) !u32 { |
| | 113 | return @intCast(try header.numeric(100, 8)); |
| | 114 | } |
| | 115 | |
| 112 | pub fn fileSize(header: Header) !u64 { | 116 | pub fn fileSize(header: Header) !u64 { |
| 113 | return header.numeric(124, 12); | 117 | return header.numeric(124, 12); |
| 114 | } | 118 | } |
| ... | @@ -429,6 +433,7 @@ fn Iterator(comptime ReaderType: type) type { | ... | @@ -429,6 +433,7 @@ fn Iterator(comptime ReaderType: type) type { |
| 429 | name: []const u8, // name of file, symlink or directory | 433 | name: []const u8, // name of file, symlink or directory |
| 430 | link_name: []const u8, // target name of symlink | 434 | link_name: []const u8, // target name of symlink |
| 431 | size: usize, // size of the file in bytes | 435 | size: usize, // size of the file in bytes |
| | 436 | mode: u32, |
| 432 | file_type: Header.FileType, | 437 | file_type: Header.FileType, |
| 433 | | 438 | |
| 434 | reader: *BufferedReaderType, | 439 | reader: *BufferedReaderType, |
| ... | @@ -471,6 +476,7 @@ fn Iterator(comptime ReaderType: type) type { | ... | @@ -471,6 +476,7 @@ fn Iterator(comptime ReaderType: type) type { |
| 471 | .link_name = self.scratch.link_name, | 476 | .link_name = self.scratch.link_name, |
| 472 | .size = self.scratch.size, | 477 | .size = self.scratch.size, |
| 473 | .reader = &self.reader, | 478 | .reader = &self.reader, |
| | 479 | .mode = try header.mode(), |
| 474 | }; | 480 | }; |
| 475 | self.padding = blockPadding(file.size); | 481 | self.padding = blockPadding(file.size); |
| 476 | return file; | 482 | return file; |
| ... | @@ -689,6 +695,7 @@ const TestCase = struct { | ... | @@ -689,6 +695,7 @@ const TestCase = struct { |
| 689 | const File = struct { | 695 | const File = struct { |
| 690 | name: []const u8, | 696 | name: []const u8, |
| 691 | size: usize = 0, | 697 | size: usize = 0, |
| | 698 | mode: u32 = 0, |
| 692 | link_name: []const u8 = &[0]u8{}, | 699 | link_name: []const u8 = &[0]u8{}, |
| 693 | file_type: Header.FileType = .normal, | 700 | file_type: Header.FileType = .normal, |
| 694 | truncated: bool = false, // when there is no file body, just header, usefull for huge files | 701 | truncated: bool = false, // when there is no file body, just header, usefull for huge files |
| ... | @@ -713,10 +720,12 @@ test "tar run Go test cases" { | ... | @@ -713,10 +720,12 @@ test "tar run Go test cases" { |
| 713 | .{ | 720 | .{ |
| 714 | .name = "small.txt", | 721 | .name = "small.txt", |
| 715 | .size = 5, | 722 | .size = 5, |
| | 723 | .mode = 0o640, |
| 716 | }, | 724 | }, |
| 717 | .{ | 725 | .{ |
| 718 | .name = "small2.txt", | 726 | .name = "small2.txt", |
| 719 | .size = 11, | 727 | .size = 11, |
| | 728 | .mode = 0o640, |
| 720 | }, | 729 | }, |
| 721 | }, | 730 | }, |
| 722 | .chksums = &[_][]const u8{ | 731 | .chksums = &[_][]const u8{ |
| ... | @@ -734,10 +743,12 @@ test "tar run Go test cases" { | ... | @@ -734,10 +743,12 @@ test "tar run Go test cases" { |
| 734 | .{ | 743 | .{ |
| 735 | .name = "small.txt", | 744 | .name = "small.txt", |
| 736 | .size = 5, | 745 | .size = 5, |
| | 746 | .mode = 0o640, |
| 737 | }, | 747 | }, |
| 738 | .{ | 748 | .{ |
| 739 | .name = "small2.txt", | 749 | .name = "small2.txt", |
| 740 | .size = 11, | 750 | .size = 11, |
| | 751 | .mode = 0o640, |
| 741 | }, | 752 | }, |
| 742 | }, | 753 | }, |
| 743 | .chksums = &[_][]const u8{ | 754 | .chksums = &[_][]const u8{ |
| ... | @@ -751,10 +762,12 @@ test "tar run Go test cases" { | ... | @@ -751,10 +762,12 @@ test "tar run Go test cases" { |
| 751 | .{ | 762 | .{ |
| 752 | .name = "small.txt", | 763 | .name = "small.txt", |
| 753 | .size = 5, | 764 | .size = 5, |
| | 765 | .mode = 0o444, |
| 754 | }, | 766 | }, |
| 755 | .{ | 767 | .{ |
| 756 | .name = "small2.txt", | 768 | .name = "small2.txt", |
| 757 | .size = 11, | 769 | .size = 11, |
| | 770 | .mode = 0o444, |
| 758 | }, | 771 | }, |
| 759 | }, | 772 | }, |
| 760 | .chksums = &[_][]const u8{ | 773 | .chksums = &[_][]const u8{ |
| ... | @@ -768,11 +781,13 @@ test "tar run Go test cases" { | ... | @@ -768,11 +781,13 @@ test "tar run Go test cases" { |
| 768 | .{ | 781 | .{ |
| 769 | .name = "a/123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100", | 782 | .name = "a/123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100", |
| 770 | .size = 7, | 783 | .size = 7, |
| | 784 | .mode = 0o664, |
| 771 | }, | 785 | }, |
| 772 | .{ | 786 | .{ |
| 773 | .name = "a/b", | 787 | .name = "a/b", |
| 774 | .size = 0, | 788 | .size = 0, |
| 775 | .file_type = .symbolic_link, | 789 | .file_type = .symbolic_link, |
| | 790 | .mode = 0o777, |
| 776 | .link_name = "123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100", | 791 | .link_name = "123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100", |
| 777 | }, | 792 | }, |
| 778 | }, | 793 | }, |
| ... | @@ -793,6 +808,7 @@ test "tar run Go test cases" { | ... | @@ -793,6 +808,7 @@ test "tar run Go test cases" { |
| 793 | .name = "foo", | 808 | .name = "foo", |
| 794 | .size = 999, | 809 | .size = 999, |
| 795 | .file_type = .normal, | 810 | .file_type = .normal, |
| | 811 | .mode = 0o640, |
| 796 | }, | 812 | }, |
| 797 | }, | 813 | }, |
| 798 | .chksums = &[_][]const u8{ | 814 | .chksums = &[_][]const u8{ |
| ... | @@ -833,6 +849,7 @@ test "tar run Go test cases" { | ... | @@ -833,6 +849,7 @@ test "tar run Go test cases" { |
| 833 | .name = "P1050238.JPG.log", | 849 | .name = "P1050238.JPG.log", |
| 834 | .size = 14, | 850 | .size = 14, |
| 835 | .file_type = .normal, | 851 | .file_type = .normal, |
| | 852 | .mode = 0o664, |
| 836 | }, | 853 | }, |
| 837 | }, | 854 | }, |
| 838 | .chksums = &[_][]const u8{ | 855 | .chksums = &[_][]const u8{ |
| ... | @@ -847,11 +864,13 @@ test "tar run Go test cases" { | ... | @@ -847,11 +864,13 @@ test "tar run Go test cases" { |
| 847 | .name = "small.txt", | 864 | .name = "small.txt", |
| 848 | .size = 5, | 865 | .size = 5, |
| 849 | .file_type = .normal, | 866 | .file_type = .normal, |
| | 867 | .mode = 0o644, |
| 850 | }, | 868 | }, |
| 851 | .{ | 869 | .{ |
| 852 | .name = "small2.txt", | 870 | .name = "small2.txt", |
| 853 | .size = 11, | 871 | .size = 11, |
| 854 | .file_type = .normal, | 872 | .file_type = .normal, |
| | 873 | .mode = 0o644, |
| 855 | }, | 874 | }, |
| 856 | }, | 875 | }, |
| 857 | .chksums = &[_][]const u8{ | 876 | .chksums = &[_][]const u8{ |
| ... | @@ -890,6 +909,7 @@ test "tar run Go test cases" { | ... | @@ -890,6 +909,7 @@ test "tar run Go test cases" { |
| 890 | .files = &[_]TestCase.File{ | 909 | .files = &[_]TestCase.File{ |
| 891 | .{ | 910 | .{ |
| 892 | .name = "0123456789", | 911 | .name = "0123456789", |
| | 912 | .mode = 0o644, |
| 893 | }, | 913 | }, |
| 894 | }, | 914 | }, |
| 895 | }, | 915 | }, |
| ... | @@ -898,6 +918,7 @@ test "tar run Go test cases" { | ... | @@ -898,6 +918,7 @@ test "tar run Go test cases" { |
| 898 | .files = &[_]TestCase.File{ | 918 | .files = &[_]TestCase.File{ |
| 899 | .{ | 919 | .{ |
| 900 | .name = "☺☻☹☺☻☹☺☻☹☺☻☹☺☻☹☺☻☹☺☻☹☺☻☹☺☻☹☺☻☹☺☻☹☺☻☹☺☻☹☺☻☹☺☻☹☺☻☹☺☻☹☺☻☹", | 920 | .name = "☺☻☹☺☻☹☺☻☹☺☻☹☺☻☹☺☻☹☺☻☹☺☻☹☺☻☹☺☻☹☺☻☹☺☻☹☺☻☹☺☻☹☺☻☹☺☻☹☺☻☹☺☻☹", |
| | 921 | .mode = 0o644, |
| 901 | }, | 922 | }, |
| 902 | }, | 923 | }, |
| 903 | }, | 924 | }, |
| ... | @@ -906,6 +927,7 @@ test "tar run Go test cases" { | ... | @@ -906,6 +927,7 @@ test "tar run Go test cases" { |
| 906 | .files = &[_]TestCase.File{ | 927 | .files = &[_]TestCase.File{ |
| 907 | .{ | 928 | .{ |
| 908 | .name = "hi\x80\x81\x82\x83bye", | 929 | .name = "hi\x80\x81\x82\x83bye", |
| | 930 | .mode = 0o644, |
| 909 | }, | 931 | }, |
| 910 | }, | 932 | }, |
| 911 | }, | 933 | }, |
| ... | @@ -948,6 +970,7 @@ test "tar run Go test cases" { | ... | @@ -948,6 +970,7 @@ test "tar run Go test cases" { |
| 948 | .files = &[_]TestCase.File{ | 970 | .files = &[_]TestCase.File{ |
| 949 | .{ | 971 | .{ |
| 950 | .name = "file", | 972 | .name = "file", |
| | 973 | .mode = 0o644, |
| 951 | }, | 974 | }, |
| 952 | }, | 975 | }, |
| 953 | }, | 976 | }, |
| ... | @@ -968,6 +991,7 @@ test "tar run Go test cases" { | ... | @@ -968,6 +991,7 @@ test "tar run Go test cases" { |
| 968 | .name = "tmp/16gig.txt", | 991 | .name = "tmp/16gig.txt", |
| 969 | .size = 16 * 1024 * 1024 * 1024, | 992 | .size = 16 * 1024 * 1024 * 1024, |
| 970 | .truncated = true, | 993 | .truncated = true, |
| | 994 | .mode = 0o640, |
| 971 | }, | 995 | }, |
| 972 | }, | 996 | }, |
| 973 | }, | 997 | }, |
| ... | @@ -978,6 +1002,7 @@ test "tar run Go test cases" { | ... | @@ -978,6 +1002,7 @@ test "tar run Go test cases" { |
| 978 | .{ | 1002 | .{ |
| 979 | .name = "longname/" ** 15 ++ "16gig.txt", | 1003 | .name = "longname/" ** 15 ++ "16gig.txt", |
| 980 | .size = 16 * 1024 * 1024 * 1024, | 1004 | .size = 16 * 1024 * 1024 * 1024, |
| | 1005 | .mode = 0o644, |
| 981 | .truncated = true, | 1006 | .truncated = true, |
| 982 | }, | 1007 | }, |
| 983 | }, | 1008 | }, |
| ... | @@ -1002,6 +1027,7 @@ test "tar run Go test cases" { | ... | @@ -1002,6 +1027,7 @@ test "tar run Go test cases" { |
| 1002 | try std.testing.expectEqualStrings(expected.name, actual.name); | 1027 | try std.testing.expectEqualStrings(expected.name, actual.name); |
| 1003 | try std.testing.expectEqual(expected.size, actual.size); | 1028 | try std.testing.expectEqual(expected.size, actual.size); |
| 1004 | try std.testing.expectEqual(expected.file_type, actual.file_type); | 1029 | try std.testing.expectEqual(expected.file_type, actual.file_type); |
| | 1030 | try std.testing.expectEqual(expected.mode, actual.mode); |
| 1005 | try std.testing.expectEqualStrings(expected.link_name, actual.link_name); | 1031 | try std.testing.expectEqualStrings(expected.link_name, actual.link_name); |
| 1006 | | 1032 | |
| 1007 | if (case.chksums.len > i) { | 1033 | if (case.chksums.len > i) { |