|
63 | 63 | my $have_top_dir = 1;
|
64 | 64 | my ($top_dir, %files);
|
65 | 65 |
|
| 66 | + my $next_path = ''; |
| 67 | + |
66 | 68 | while (read(I, $_, 512) == 512) {
|
67 | 69 | my ($name, $mode, $uid, $gid, $size, $mtime,
|
68 | 70 | $chksum, $typeflag, $linkname, $magic,
|
69 | 71 | $version, $uname, $gname, $devmajor, $devminor,
|
70 | 72 | $prefix) = unpack 'Z100 Z8 Z8 Z8 Z12 Z12
|
71 | 73 | Z8 Z1 Z100 Z6
|
72 | 74 | Z2 Z32 Z32 Z8 Z8 Z*', $_;
|
| 75 | + |
| 76 | + unless ($next_path eq '') { |
| 77 | + # Recover name from previous extended header |
| 78 | + $name = $next_path; |
| 79 | + $next_path = ''; |
| 80 | + } |
| 81 | + |
73 | 82 | last unless length($name);
|
74 | 83 | if ($name eq '././@LongLink') {
|
75 | 84 | # GNU tar extension
|
|
90 | 99 | Z8 Z1 Z100 Z6
|
91 | 100 | Z2 Z32 Z32 Z8 Z8 Z*', $_;
|
92 | 101 | }
|
93 |
| - next if $name =~ m{/\z}; |
94 | 102 | $mode = oct $mode;
|
95 | 103 | $size = oct $size;
|
96 | 104 | $mtime = oct $mtime;
|
97 | 105 | next if $typeflag == 5; # directory
|
98 | 106 |
|
99 |
| - if ($typeflag != 1) { # handle hard links later |
| 107 | + if ($typeflag eq 'x') { # extended header |
| 108 | + # If extended header, check for path |
| 109 | + my $pax_header = ''; |
| 110 | + while ($size > 0 && read(I, $_, 512) == 512) { |
| 111 | + $pax_header = $pax_header . substr($_, 0, $size); |
| 112 | + $size -= 512; |
| 113 | + } |
| 114 | + |
| 115 | + my @lines = split /\n/, $pax_header; |
| 116 | + foreach my $line (@lines) { |
| 117 | + my ($len, $entry) = split / /, $line; |
| 118 | + my ($key, $value) = split /=/, $entry; |
| 119 | + if ($key eq 'path') { |
| 120 | + $next_path = $value; |
| 121 | + } |
| 122 | + } |
| 123 | + next; |
| 124 | + } elsif ($name =~ m{/\z}) { # directory |
| 125 | + next; |
| 126 | + } elsif ($typeflag != 1) { # handle hard links later |
100 | 127 | print FI "blob\n", "mark :$next_mark\n";
|
101 | 128 | if ($typeflag == 2) { # symbolic link
|
102 | 129 | print FI "data ", length($linkname), "\n",
|
|
0 commit comments