Skip to content

Commit add2a39

Browse files
author
Tobias Simetsreiter
committed
add gnu tar FileTypes and read file name from 'L'
1 parent fa022d1 commit add2a39

File tree

1 file changed

+32
-0
lines changed

1 file changed

+32
-0
lines changed

lib/std/tar.zig

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,14 @@ pub const Header = struct {
7777
contiguous = '7',
7878
global_extended_header = 'g',
7979
extended_header = 'x',
80+
// GNU Tar variants:
81+
// https://www.gnu.org/software/tar/manual/html_node/Standard.html
82+
GNUTYPE_LONGLINK = 'K',
83+
GNUTYPE_LONGNAME = 'L',
84+
GNUTYPE_MULTIVOL = 'M',
85+
GNUTYPE_SPARSE = 'S',
86+
GNUTYPE_VOLHDR = 'V',
87+
SOLARIS_XHDTYPE = 'X',
8088
_,
8189
};
8290

@@ -255,6 +263,30 @@ pub fn pipeToFileSystem(dir: std.fs.Dir, reader: anytype, options: Options) !voi
255263
}
256264
}
257265
},
266+
.GNUTYPE_LONGNAME => {
267+
assert(std.mem.eql(u8, header.name(), "././@LongLink"));
268+
269+
while (true) {
270+
const filename_chunk = try buffer.readChunk(reader, 512);
271+
switch (filename_chunk.len) {
272+
0 => return,
273+
1...511 => return error.UnexpectedEndOfStream,
274+
else => {},
275+
}
276+
buffer.advance(512);
277+
const chunk_start = file_name_override_len;
278+
if (std.mem.indexOfScalar(u8, filename_chunk, 0)) |end| {
279+
file_name_override_len += end;
280+
assert(file_name_override_len < file_name_buffer.len);
281+
@memcpy(file_name_buffer[chunk_start..file_name_override_len], filename_chunk[0..end]);
282+
continue :header;
283+
} else {
284+
file_name_override_len += filename_chunk.len;
285+
assert(file_name_override_len < file_name_buffer.len);
286+
@memcpy(file_name_buffer[chunk_start..file_name_override_len], filename_chunk);
287+
}
288+
}
289+
},
258290
.extended_header => {
259291
if (file_size == 0) {
260292
buffer.advance(@intCast(rounded_file_size));

0 commit comments

Comments
 (0)