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".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.
125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 |
# File 'lib/minitar/posix_header.rb', line 125 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.
52 53 54 |
# File 'lib/minitar/posix_header.rb', line 52 def name @name end |
Class Method Details
.from_data(data) ⇒ Object
Creates a new PosixHeader from a BLOCK_SIZE-byte data buffer.
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 109 110 111 112 113 |
# File 'lib/minitar/posix_header.rb', line 73 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.
61 62 63 |
# File 'lib/minitar/posix_header.rb', line 61 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.
67 68 69 70 |
# File 'lib/minitar/posix_header.rb', line 67 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.
144 145 146 |
# File 'lib/minitar/posix_header.rb', line 144 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.
155 156 157 |
# File 'lib/minitar/posix_header.rb', line 155 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.
160 161 162 163 |
# File 'lib/minitar/posix_header.rb', line 160 def to_s update_checksum header(@checksum) end |
#update_checksum ⇒ Object
Update the checksum field.
167 168 169 170 |
# File 'lib/minitar/posix_header.rb', line 167 def update_checksum hh = header(" " * 8) @checksum = oct(calculate_checksum(hh), 6) end |
#valid? ⇒ Boolean
Indicates if the header has a valid magic value.
149 150 151 |
# File 'lib/minitar/posix_header.rb', line 149 def valid? empty? || @magic == MAGIC_BYTES end |