A header for a tar file

Methods
C
E
F
H
N
O
U
Constants
FIELDS = [ :checksum, :devmajor, :devminor, :gid, :gname, :linkname, :magic, :mode, :mtime, :name, :prefix, :size, :typeflag, :uid, :uname, :version, ]
 

Fields in the tar header

PACK_FORMAT = 'a100' + # name 'a8' + # mode 'a8' + # uid 'a8' + # gid 'a12' + # size 'a12' + # mtime 'a7a' + # chksum 'a' + # typeflag 'a100' + # linkname 'a6' + # magic 'a2' + # version 'a32' + # uname 'a32' + # gname 'a8' + # devmajor 'a8' + # devminor 'a155'
 

Pack format for a tar header

UNPACK_FORMAT = 'A100' + # name 'A8' + # mode 'A8' + # uid 'A8' + # gid 'A12' + # size 'A12' + # mtime 'A8' + # checksum 'A' + # typeflag 'A100' + # linkname 'A6' + # magic 'A2' + # version 'A32' + # uname 'A32' + # gname 'A8' + # devmajor 'A8' + # devminor 'A155'
 

Unpack format for a tar header

Class Public methods
from(stream)

Creates a tar header from IO stream

# File ../ruby/lib/rubygems/package/tar_header.rb, line 98
def self.from(stream)
  header = stream.read 512
  empty = (header == "\0" * 512)

  fields = header.unpack 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

  new :name     => name,
      :mode     => mode,
      :uid      => uid,
      :gid      => gid,
      :size     => size,
      :mtime    => mtime,
      :checksum => checksum,
      :typeflag => typeflag,
      :linkname => linkname,
      :magic    => magic,
      :version  => version,
      :uname    => uname,
      :gname    => gname,
      :devmajor => devmajor,
      :devminor => devminor,
      :prefix   => prefix,

      :empty    => empty

  # HACK unfactor for Rubinius
  #new :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 => empty
end
new(vals)

Creates a new TarHeader using vals

# File ../ruby/lib/rubygems/package/tar_header.rb, line 164
def initialize(vals)
  unless vals[:name] && vals[:size] && vals[:prefix] && vals[:mode] then
    raise ArgumentError, ":name, :size, :prefix and :mode required"
  end

  vals[:uid] ||= 0
  vals[:gid] ||= 0
  vals[:mtime] ||= 0
  vals[:checksum] ||= ""
  vals[:typeflag] ||= "0"
  vals[:magic] ||= "ustar"
  vals[:version] ||= "00"
  vals[:uname] ||= "wheel"
  vals[:gname] ||= "wheel"
  vals[:devmajor] ||= 0
  vals[:devminor] ||= 0

  FIELDS.each do |name|
    instance_variable_set "@#{name}", vals[name]
  end

  @empty = vals[:empty]
end
Instance Public methods
empty?()

Is the tar entry empty?

# File ../ruby/lib/rubygems/package/tar_header.rb, line 191
def empty?
  @empty
end
update_checksum()

Updates the TarHeader's checksum

# File ../ruby/lib/rubygems/package/tar_header.rb, line 223
def update_checksum
  header = header " " * 8
  @checksum = oct calculate_checksum(header), 6
end
Instance Private methods
calculate_checksum(header)
# File ../ruby/lib/rubygems/package/tar_header.rb, line 230
def calculate_checksum(header)
  header.unpack("C*").inject { |a, b| a + b }
end
header(checksum = @checksum)
# File ../ruby/lib/rubygems/package/tar_header.rb, line 234
def header(checksum = @checksum)
  header = [
    name,
    oct(mode, 7),
    oct(uid, 7),
    oct(gid, 7),
    oct(size, 11),
    oct(mtime, 11),
    checksum,
    " ",
    typeflag,
    linkname,
    magic,
    oct(version, 2),
    uname,
    gname,
    oct(devmajor, 7),
    oct(devminor, 7),
    prefix
  ]

  header = header.pack PACK_FORMAT

  header << ("\0" * ((512 - header.size) % 512))
end
oct(num, len)
# File ../ruby/lib/rubygems/package/tar_header.rb, line 260
def oct(num, len)
  "%0#{len}o" % num
end