Implements the POSIX tar header as a Ruby class. The structure of the POSIX tar header is:
struct tarfile_entry_posix { // pack/unpack char name[100]; // ASCII (+ Z unless filled) a100/Z100 char mode[8]; // 0 padded, octal, null a8 /A8 char uid[8]; // 0 padded, octal, null a8 /A8 char gid[8]; // 0 padded, octal, null a8 /A8 char size[12]; // 0 padded, octal, null a12 /A12 char mtime[12]; // 0 padded, octal, null a12 /A12 char checksum[8]; // 0 padded, octal, null, space a8 /A8 char typeflag[1]; // see below a /a char linkname[100]; // ASCII + (Z unless filled) a100/Z100 char magic[6]; // "ustar\0" a6 /A6 char version[2]; // "00" a2 /A2 char uname[32]; // ASCIIZ a32 /Z32 char gname[32]; // ASCIIZ a32 /Z32 char devmajor[8]; // 0 padded, octal, null a8 /A8 char devminor[8]; // 0 padded, octal, null a8 /A8 char prefix[155]; // ASCII (+ Z unless filled) a155/Z155 };
The typeflag is one of several known values.
POSIX indicates that “A POSIX-compliant implementation must treat any unrecognized typeflag value as a regular file.”
All fields available in a POSIX tar(1) header.
The pack format passed to Array#pack for encoding a header.
The unpack format passed to String#unpack for decoding a header.
Fields that may be set in a POSIX tar(1) header.
Fields that must be set in a POSIX tar(1) header.
The minor device ID. Not currently used.
The name of the file. By default, limited to 100 bytes. Required. May be longer (up to BLOCK_SIZE bytes) if using the GNU long name tar extension.
Creates a new PosixHeader from a BLOCK_SIZE-byte data buffer.
# File lib/archive/tar/minitar/posix_header.rb, line 77 def from_data(data) fields = data.unpack(HEADER_UNPACK_FORMAT) name = fields.shift mode = fields.shift.oct uid = fields.shift.oct gid = fields.shift.oct size = fields.shift.oct mtime = fields.shift.oct checksum = fields.shift.oct typeflag = fields.shift linkname = fields.shift magic = fields.shift version = fields.shift.oct uname = fields.shift gname = fields.shift devmajor = fields.shift.oct devminor = fields.shift.oct prefix = fields.shift empty = !data.each_byte.any?(&:nonzero?) new( :name => name, :mode => mode, :uid => uid, :gid => gid, :size => size, :mtime => mtime, :checksum => checksum, :typeflag => typeflag, :magic => magic, :version => version, :uname => uname, :gname => gname, :devmajor => devmajor, :devminor => devminor, :prefix => prefix, :empty => empty, :linkname => linkname ) end
Creates a new PosixHeader from a data stream.
# File lib/archive/tar/minitar/posix_header.rb, line 65 def from_stream(stream) from_data(stream.read(BLOCK_SIZE)) end
Creates a new PosixHeader. A PosixHeader cannot be created unless
name
, size
, prefix
, and
mode
are provided.
# File lib/archive/tar/minitar/posix_header.rb, line 122 def initialize(v) REQUIRED_FIELDS.each do |f| raise ArgumentError, "Field #{f} is required." unless v.key?(f) end v[:mtime] = v[:mtime].to_i v[:checksum] ||= '' v[:typeflag] ||= '0' v[:magic] ||= 'ustar' v[:version] ||= '00' FIELDS.each do |f| instance_variable_set("@#{f}", v[f]) end @empty = v[:empty] end
Creates a new PosixHeader from a data stream. Deprecated; use ::from_stream instead.
# File lib/archive/tar/minitar/posix_header.rb, line 71 def new_from_stream(stream) warn "#{__method__} has been deprecated; use from_stream instead." from_stream(stream) end
Indicates if the header was an empty header.
# File lib/archive/tar/minitar/posix_header.rb, line 141 def empty? @empty end
Returns true
if the header is a long name special header which
indicates that the next block of data is the filename.
# File lib/archive/tar/minitar/posix_header.rb, line 147 def long_name? typeflag == 'L' && name == '././@LongLink' end
A string representation of the header.
# File lib/archive/tar/minitar/posix_header.rb, line 152 def to_s update_checksum header(@checksum) end
Update the checksum field.
# File lib/archive/tar/minitar/posix_header.rb, line 159 def update_checksum hh = header(' ' * 8) @checksum = oct(calculate_checksum(hh), 6) end