class Archive::Tar::Format

Constants

DEC_TYPES
ENC_TYPES

Public Class Methods

blocks_for_bytes(bytes) click to toggle source

Calculate quantity of blocks

# File lib/archive/tar/format.rb, line 143
def blocks_for_bytes(bytes)
  bytes % 512 == 0 ? bytes / 512 : (bytes + 512 - bytes % 512) / 512
end
calculate_checksum(header) click to toggle source

Generate checksum with header

# File lib/archive/tar/format.rb, line 91
def calculate_checksum(header)
  checksum = 0
  
  header.each_byte do |byte|
    checksum += byte
  end
  
  checksum.to_s(8).rjust(6, " ") + "\0 "
end
detect_type(header) click to toggle source

Detect type of tar file by header

# File lib/archive/tar/format.rb, line 83
def detect_type(header)
  return :ustar if header[257, 6] == "ustar0"
  return :gnu if header[257, 6] == "ustar "
  
  :other
end
pack_header(header) click to toggle source

Pack header from Stat

# File lib/archive/tar/format.rb, line 102
def pack_header(header)
  blob = ""
  
  blob += header.path.ljust(100, "\0")
  blob += header.mode.to_s(8).rjust(8, "0")
  blob += header.uid.to_s(8).rjust(8, "0")
  blob += header.gid.to_s(8).rjust(8, "0")
  blob += header.size.to_s(8).rjust(12, "0")
  blob += header.mtime.to_i.to_s(8).rjust(12, "0")
  blob += " " * 8
  blob += ENC_TYPES[header.type]
  blob += header.dest.ljust(100, "\0")
  
  case header.format
  when :ustar
    blob += "ustar\000"
  when :gnu
    blob += "ustar  \0"
  end
  
  if header.gnu? || header.ustar?
    blob += header.user.ljust(32, "\0")
    blob += header.group.ljust(32, "\0")
    blob += header.major.to_s(8).rjust(8, "0")
    blob += header.minor.to_s(8).rjust(8, "0")
    
    if header.gnu?
      blob += header.atime.to_i.to_s(8).rjust(12, "0")
      blob += header.ctime.to_i.to_s(8).rjust(12, "0")
    end
  end
  
  pad_length = 512 - blob.bytesize
  blob += "\0" * pad_length
  
  blob[148, 8] = calculate_checksum(blob)
  
  blob
end
strip_nuls(string) click to toggle source

Remove all NUL bytes at the end of a string

# File lib/archive/tar/format.rb, line 44
def strip_nuls(string)
  until string[-1] != "\0"
    string = string[0..-2]
  end
  
  string
end
unpack_header(header) click to toggle source

Transform tar header to Stat

# File lib/archive/tar/format.rb, line 53
def unpack_header(header)
  new_obj = Archive::Tar::Stat.new

  new_obj.path = strip_nuls(header[0, 100])
  new_obj.mode = header[100, 8].oct
  new_obj.uid = header[108, 8].oct
  new_obj.gid = header[116, 8].oct
  new_obj.size = header[124, 12].oct
  new_obj.mtime = Time.at(header[136, 12].oct)
  new_obj.checksum = header[148, 8].oct
  new_obj.type = DEC_TYPES[header[156]]
  new_obj.dest = strip_nuls(header[157, 100])
  new_obj.format = header[257, 5] == "ustar" ?
    ( header[257, 6] == "ustar " ? :gnu : :ustar ) : :other
  new_obj.user = strip_nuls(header[265, 32])
  new_obj.group = strip_nuls(header[297, 32])
  new_obj.major = header[329, 8].oct
  new_obj.minor = header[337, 8].oct
  
  new_obj.path = header[345, 155].strip + new_obj.path if new_obj.ustar?
  
  if new_obj.gnu?
    new_obj.atime = Time.at(header[345, 12].oct)
    new_obj.ctime = Time.at(header[357, 12].oct)
  end
  
  new_obj
end