Class: Archive::Tar::Minitar::PosixHeader
- Inherits:
-
Object
- Object
- Archive::Tar::Minitar::PosixHeader
- Includes:
- ByteSize
- Defined in:
- lib/archive/tar/minitar/posix_header.rb
Overview
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.”
Constant Summary collapse
- BLOCK_SIZE =
512
- MAGIC_BYTES =
'ustar'.freeze
- GNU_EXT_LONG_LINK =
'././@LongLink'
- REQUIRED_FIELDS =
Fields that must be set in a POSIX tar(1) header.
[ :name, :size, :prefix, :mode ].freeze
- OPTIONAL_FIELDS =
Fields that may be set in a POSIX tar(1) header.
[ :uid, :gid, :mtime, :checksum, :typeflag, :linkname, :magic, :version, :uname, :gname, :devmajor, :devminor ].freeze
- FIELDS =
All fields available in a POSIX tar(1) header.
(REQUIRED_FIELDS + OPTIONAL_FIELDS).freeze
- HEADER_PACK_FORMAT =
The pack format passed to Array#pack for encoding a header.
'a100a8a8a8a12a12a7aaa100a6a2a32a32a8a8a155'.freeze
- HEADER_UNPACK_FORMAT =
The unpack format passed to String#unpack for decoding a header.
'Z100A8A8A8A12A12A8aZ100A6A2Z32Z32A8A8Z155'.freeze
Instance Attribute Summary collapse
-
#name ⇒ Object
The name of the file.
Class Method Summary collapse
-
.from_data(data) ⇒ Object
Creates a new PosixHeader from a BLOCK_SIZE-byte data buffer.
-
.from_stream(stream) ⇒ Object
Creates a new PosixHeader from a data stream.
-
.new_from_stream(stream) ⇒ Object
Creates a new PosixHeader from a data stream.
Instance Method Summary collapse
-
#empty? ⇒ Boolean
Indicates if the header was an empty header.
-
#initialize(v) ⇒ PosixHeader
constructor
Creates a new PosixHeader.
-
#long_name? ⇒ Boolean
Returns
true
if the header is a long name special header which indicates that the next block of data is the filename. -
#to_s ⇒ Object
(also: #to_str)
A string representation of the header.
-
#update_checksum ⇒ Object
Update the checksum field.
-
#valid? ⇒ Boolean
Indicates if the header has a valid magic value.
Constructor Details
#initialize(v) ⇒ PosixHeader
Creates a new PosixHeader. A PosixHeader cannot be created unless name
, size
, prefix
, and mode
are provided.
133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 |
# File 'lib/archive/tar/minitar/posix_header.rb', line 133 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] ||= MAGIC_BYTES v[:version] ||= '00' FIELDS.each do |f| instance_variable_set("@#{f}", v[f]) end @empty = v[:empty] end |
Instance Attribute Details
#name ⇒ Object
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.
60 61 62 |
# File 'lib/archive/tar/minitar/posix_header.rb', line 60 def name @name end |
Class Method Details
.from_data(data) ⇒ Object
Creates a new PosixHeader from a BLOCK_SIZE-byte data buffer.
81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 |
# File 'lib/archive/tar/minitar/posix_header.rb', line 81 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 = strict_oct(fields.shift) 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 |
.from_stream(stream) ⇒ Object
Creates a new PosixHeader from a data stream.
69 70 71 |
# File 'lib/archive/tar/minitar/posix_header.rb', line 69 def from_stream(stream) from_data(stream.read(BLOCK_SIZE)) end |
.new_from_stream(stream) ⇒ Object
Creates a new PosixHeader from a data stream. Deprecated; use PosixHeader.from_stream instead.
75 76 77 78 |
# File 'lib/archive/tar/minitar/posix_header.rb', line 75 def new_from_stream(stream) warn "#{__method__} has been deprecated; use from_stream instead." from_stream(stream) end |
Instance Method Details
#empty? ⇒ Boolean
Indicates if the header was an empty header.
152 153 154 |
# File 'lib/archive/tar/minitar/posix_header.rb', line 152 def empty? @empty end |
#long_name? ⇒ Boolean
Returns true
if the header is a long name special header which indicates that the next block of data is the filename.
163 164 165 |
# File 'lib/archive/tar/minitar/posix_header.rb', line 163 def long_name? typeflag == 'L' && name == GNU_EXT_LONG_LINK end |
#to_s ⇒ Object Also known as: to_str
A string representation of the header.
168 169 170 171 |
# File 'lib/archive/tar/minitar/posix_header.rb', line 168 def to_s update_checksum header(@checksum) end |
#update_checksum ⇒ Object
Update the checksum field.
175 176 177 178 |
# File 'lib/archive/tar/minitar/posix_header.rb', line 175 def update_checksum hh = header(' ' * 8) @checksum = oct(calculate_checksum(hh), 6) end |
#valid? ⇒ Boolean
Indicates if the header has a valid magic value.
157 158 159 |
# File 'lib/archive/tar/minitar/posix_header.rb', line 157 def valid? empty? || @magic == MAGIC_BYTES end |