@@ -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