#!/usr/bin/env perl use strict; use warnings; my @entries = ( # filename mode type content ['./PaxHeaders/file', oct(644), 'x', "57 SCHILY.xattr.security.capability=\x01\0\0\x02\0\x20\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x0a"], ['file', oct(644), 0, ''], ); my $num_entries = 0; foreach my $file (@entries) { my ($fname, $mode, $type, $content) = @{$file}; my $entry = pack( 'a100 a8 a8 a8 a12 a12 A8 a1 a100 a6 a2 a32 a32 a8 a8 a155 x12', $fname, sprintf('%07o', $mode), sprintf('%07o', 0), # uid sprintf('%07o', 0), # gid sprintf('%011o', length $content), # size sprintf('%011o', 0), # mtime '', # checksum $type, '', # linkname "ustar", # magic "00", # version '', # username '', # groupname '', # dev major '', # dev minor '', # prefix ); # compute and insert checksum substr($entry, 148, 7) = sprintf("%06o\0", unpack("%16C*", $entry)); print $entry; $num_entries += 1; if (length $content) { print(pack 'a512', $content); $num_entries += 1; } } # https://www.gnu.org/software/tar/manual/html_node/Standard.html # # Physically, an archive consists of a series of file entries terminated by an # end-of-archive entry, which consists of two 512 blocks of zero bytes. At the # end of the archive file there are two 512-byte blocks filled with binary # zeros as an end-of-file marker. print(pack 'a512', ''); print(pack 'a512', ''); $num_entries += 2; # https://www.gnu.org/software/tar/manual/html_section/tar_76.html # # Some devices requires that all write operations be a multiple of a certain # size, and so, tar pads the archive out to the next record boundary. # # The default blocking factor is 20. With a block size of 512 bytes, we get a # record size of 10240. for (my $i = $num_entries ; $i < 20 ; $i++) { print(pack 'a512', ''); }