Class: Minitar::PosixHeader
- Inherits:
-
Object
- Object
- Minitar::PosixHeader
- Defined in:
- lib/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"- 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"- HEADER_UNPACK_FORMAT =
The unpack format passed to String#unpack for decoding a header.
"Z100A8A8A8a12A12A8aZ100A6A2Z32Z32A8A8Z155"
Instance Attribute Summary collapse
-
#size ⇒ Object
writeonly
Sets the attribute size.
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.
Instance Method Summary collapse
-
#empty? ⇒ Boolean
Indicates if the header was an empty header.
-
#initialize(v) ⇒ PosixHeader
constructor
Creates a new PosixHeader.
-
#long_name=(value) ⇒ Object
Sets the
nameto thevalueprovided and clearsprefix. -
#long_name? ⇒ Boolean
Returns
trueif the header is a long name special header which indicates that the next block of data is the filename. - #name=(value) ⇒ Object
-
#pax_header? ⇒ Boolean
Returns
trueif the header is a PAX extended header which contains metadata for the next file entry. -
#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.
136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 |
# File 'lib/minitar/posix_header.rb', line 136 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] valid_name!(v[:name]) unless v[:empty] end |
Instance Attribute Details
#size=(value) ⇒ Object (writeonly)
Sets the attribute size
56 57 58 |
# File 'lib/minitar/posix_header.rb', line 56 def size=(value) @size = value end |
Class Method Details
.from_data(data) ⇒ Object
Creates a new PosixHeader from a BLOCK_SIZE-byte data buffer.
68 69 70 71 72 73 74 75 76 77 78 79 80 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 |
# File 'lib/minitar/posix_header.rb', line 68 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 = parse_numeric_field(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.
65 |
# File 'lib/minitar/posix_header.rb', line 65 def from_stream(stream) = from_data(stream.read(BLOCK_SIZE)) |
Instance Method Details
#empty? ⇒ Boolean
Indicates if the header was an empty header.
157 |
# File 'lib/minitar/posix_header.rb', line 157 def empty? = @empty |
#long_name=(value) ⇒ Object
Sets the name to the value provided and clears prefix.
Used by Minitar::Reader#each_entry to set the long name when processing GNU long filename extensions.
The value must be the complete name, including leading directory components.
176 177 178 179 180 181 |
# File 'lib/minitar/posix_header.rb', line 176 def long_name=(value) valid_name!(value) @prefix = "" @name = value 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.
164 |
# File 'lib/minitar/posix_header.rb', line 164 def long_name? = typeflag == "L" && name == GNU_EXT_LONG_LINK |
#name=(value) ⇒ Object
51 52 53 54 |
# File 'lib/minitar/posix_header.rb', line 51 def name=(value) valid_name!(value) @name = value end |
#pax_header? ⇒ Boolean
Returns true if the header is a PAX extended header which contains metadata for the next file entry.
168 |
# File 'lib/minitar/posix_header.rb', line 168 def pax_header? = typeflag == "x" |
#to_s ⇒ Object Also known as: to_str
A string representation of the header.
184 185 186 187 |
# File 'lib/minitar/posix_header.rb', line 184 def to_s update_checksum header(@checksum) end |
#update_checksum ⇒ Object
Update the checksum field.
193 194 195 196 |
# File 'lib/minitar/posix_header.rb', line 193 def update_checksum hh = header(" " * 8) @checksum = oct(calculate_checksum(hh), 6) end |
#valid? ⇒ Boolean
Indicates if the header has a valid magic value.
160 |
# File 'lib/minitar/posix_header.rb', line 160 def valid? = empty? || @magic == MAGIC_BYTES |