123456789_123456789_123456789_123456789_123456789_

Class: Gem::Package::TarHeader

Relationships & Source Files
Inherits: Object
Defined in: lib/rubygems/package/tar_header.rb

Overview

A header for a tar file

Constant Summary

  • FIELDS =

    Fields in the tar header

    # File 'lib/rubygems/package/tar_header.rb', line 36
    [
      :checksum,
      :devmajor,
      :devminor,
      :gid,
      :gname,
      :linkname,
      :magic,
      :mode,
      :mtime,
      :name,
      :prefix,
      :size,
      :typeflag,
      :uid,
      :uname,
      :version,
    ]
  • PACK_FORMAT =

    Pack format for a tar header

    # File 'lib/rubygems/package/tar_header.rb', line 58
    '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'
  • UNPACK_FORMAT =

    Unpack format for a tar header

    # File 'lib/rubygems/package/tar_header.rb', line 78
    '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'

Class Method Summary

Instance Attribute Summary

Instance Method Summary

Constructor Details

.new(vals) ⇒ TarHeader

Creates a new TarHeader using vals

[ GitHub ]

  
# File 'lib/rubygems/package/tar_header.rb', line 134

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" if vals[:typeflag].nil? || vals[:typeflag].empty?
  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

Class Method Details

.from(stream)

Creates a tar header from IO stream

[ GitHub ]

  
# File 'lib/rubygems/package/tar_header.rb', line 100

def self.from(stream)
  header = stream.read 512
  empty = (header == "\0" * 512)

  fields = header.unpack UNPACK_FORMAT

  new :name     => fields.shift,
      :mode     => strict_oct(fields.shift),
      :uid      => strict_oct(fields.shift),
      :gid      => strict_oct(fields.shift),
      :size     => strict_oct(fields.shift),
      :mtime    => strict_oct(fields.shift),
      :checksum => strict_oct(fields.shift),
      :typeflag => fields.shift,
      :linkname => fields.shift,
      :magic    => fields.shift,
      :version  => strict_oct(fields.shift),
      :uname    => fields.shift,
      :gname    => fields.shift,
      :devmajor => strict_oct(fields.shift),
      :devminor => strict_oct(fields.shift),
      :prefix   => fields.shift,

      :empty => empty
end

.strict_oct(str)

Raises:

  • (ArgumentError)
[ GitHub ]

  
# File 'lib/rubygems/package/tar_header.rb', line 126

def self.strict_oct(str)
  return str.oct if str =~ /\A[0-7]*\z/
  raise ArgumentError, "#{str.inspect} is not an octal string"
end

Instance Attribute Details

#empty?Boolean (readonly)

Is the tar entry empty?

[ GitHub ]

  
# File 'lib/rubygems/package/tar_header.rb', line 161

def empty?
  @empty
end

Instance Method Details

#==(other)

This method is for internal use only.
[ GitHub ]

  
# File 'lib/rubygems/package/tar_header.rb', line 165

def ==(other) # :nodoc:
  self.class === other and
  @checksum == other.checksum and
  @devmajor == other.devmajor and
  @devminor == other.devminor and
  @gid      == other.gid      and
  @gname    == other.gname    and
  @linkname == other.linkname and
  @magic    == other.magic    and
  @mode     == other.mode     and
  @mtime    == other.mtime    and
  @name     == other.name     and
  @prefix   == other.prefix   and
  @size     == other.size     and
  @typeflag == other.typeflag and
  @uid      == other.uid      and
  @uname    == other.uname    and
  @version  == other.version
end

#calculate_checksum(header) (private)

[ GitHub ]

  
# File 'lib/rubygems/package/tar_header.rb', line 200

def calculate_checksum(header)
  header.unpack("C*").inject { |a, b| a + b }
end

#header(checksum = @checksum) (private)

[ GitHub ]

  
# File 'lib/rubygems/package/tar_header.rb', line 204

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) (private)

[ GitHub ]

  
# File 'lib/rubygems/package/tar_header.rb', line 230

def oct(num, len)
  "%0#{len}o" % num
end

#to_s

This method is for internal use only.
[ GitHub ]

  
# File 'lib/rubygems/package/tar_header.rb', line 185

def to_s # :nodoc:
  update_checksum
  header
end

#update_checksum

Updates the TarHeader's checksum

[ GitHub ]

  
# File 'lib/rubygems/package/tar_header.rb', line 193

def update_checksum
  header = header " " * 8
  @checksum = oct calculate_checksum(header), 6
end