Class: Archive::Tar::PosixHeader
- Inherits:
-
Object
- Object
- Archive::Tar::PosixHeader
- Defined in:
- lib/archive/tar/minitar.rb
Overview
Archive::Tar::PosixHeader
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]; // ditto a8 /A8
char gid[8]; // ditto 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
may be one of the following known values:
"0"
-
Regular file. NULL should be treated as a synonym, for compatibility purposes.
"1"
-
Hard link.
"2"
-
Symbolic link.
"3"
-
Character device node.
"4"
-
Block device node.
"5"
-
Directory.
"6"
-
FIFO node.
"7"
-
Reserved.
POSIX indicates that “A POSIX-compliant implementation must treat any unrecognized typeflag value as a regular file.”
Constant Summary collapse
- FIELDS =
%w(name mode uid gid size mtime checksum typeflag linkname) + %w(magic version uname gname devmajor devminor prefix)
- HEADER_PACK_FORMAT =
"a100a8a8a8a12a12a7aaa100a6a2a32a32a8a8a155"
- HEADER_UNPACK_FORMAT =
"Z100A8A8A8A12A12A8aZ100A6A2Z32Z32A8A8Z155"
Class Method Summary collapse
-
.new_from_stream(stream, long_name = nil) ⇒ Object
Creates a new PosixHeader from a data stream.
Instance Method Summary collapse
- #empty? ⇒ Boolean
-
#initialize(vals) ⇒ PosixHeader
constructor
Creates a new PosixHeader.
- #to_s ⇒ Object
-
#update_checksum ⇒ Object
Update the checksum field.
Constructor Details
#initialize(vals) ⇒ PosixHeader
Creates a new PosixHeader. A PosixHeader cannot be created unless the #name, #size, #prefix, and #mode are provided.
103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 |
# File 'lib/archive/tar/minitar.rb', line 103 def initialize(vals) unless vals[:name] && vals[:size] && vals[:prefix] && vals[:mode] raise ArgumentError end vals[:mtime] ||= 0 vals[:checksum] ||= "" vals[:typeflag] ||= "0" vals[:magic] ||= "ustar" vals[:version] ||= "00" FIELDS.each do |field| instance_variable_set("@#{field}", vals[field.intern]) end @empty = vals[:empty] end |
Class Method Details
.new_from_stream(stream, long_name = nil) ⇒ Object
Creates a new PosixHeader from a data stream.
66 67 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 |
# File 'lib/archive/tar/minitar.rb', line 66 def self.new_from_stream(stream, long_name = nil) data = stream.read(512) 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 == "\0" * 512) if typeflag == 'L' && name == '././@LongLink' long_name = stream.read(512).rstrip return new_from_stream(stream, long_name) end new(:name => long_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) end |
Instance Method Details
#empty? ⇒ Boolean
120 121 122 |
# File 'lib/archive/tar/minitar.rb', line 120 def empty? @empty end |
#to_s ⇒ Object
124 125 126 127 |
# File 'lib/archive/tar/minitar.rb', line 124 def to_s update_checksum header(@checksum) end |
#update_checksum ⇒ Object
Update the checksum field.
130 131 132 133 |
# File 'lib/archive/tar/minitar.rb', line 130 def update_checksum hh = header(" " * 8) @checksum = oct(calculate_checksum(hh), 6) end |