Class: Archive::Ar::Format

Inherits:
Object
  • Object
show all
Defined in:
lib/archive/ar/format.rb

Class Method Summary collapse

Class Method Details

.build_header(file) ⇒ Object



11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# File 'lib/archive/ar/format.rb', line 11

def build_header(file)
  header = {
    :name => File.basename(file),
    :modified => File.mtime(file).to_i,
    :owner => File.stat(file).uid,
    :group => File.stat(file).gid,
    :mode => File.stat(file).mode,
    :size => File.size(file),
    :magic => "`\n"
  }

  data = ""
  data += "%-16s" % header[:name]
  data += "%-12s" % header[:modified]
  data += "%-6s" % header[:owner]
  data += "%-6s" % header[:group]
  data += "%-8s" % header[:mode].to_s(8)
  data += "%-10s" % header[:size]
  data += "%2s" % header[:magic]
  data
end

.extract_file(dest_dir, header, data, options = {}) ⇒ Object



60
61
62
63
64
65
66
67
68
69
70
71
# File 'lib/archive/ar/format.rb', line 60

def extract_file(dest_dir, header, data, options = {})
  file = File.join(dest_dir, header[:name])

  File.open(file, "w") do |f|
    f.write(data)
  end

  File.chmod(header[:mode], file)
  #FileUtils.chown(header[:owner], header[:group], file)

  true
end

.parse_header(data) ⇒ Object



33
34
35
36
37
38
39
40
41
42
43
44
# File 'lib/archive/ar/format.rb', line 33

def parse_header(data)
  h = data.unpack("A16 Z12 a6 a6 A8 Z10 Z2")
  {
    :name => h.shift.chomp("/"), # Remove trailing slash. Some archives have this...
    :modified => Time.at(h.shift.to_i),
    :owner => h.shift.to_i,
    :group => h.shift.to_i,
    :mode => h.shift.to_i(8),
    :size => h.shift.to_i,
    :magic => h.shift,
  }
end

.read_global_header(io) ⇒ Object



5
6
7
8
9
# File 'lib/archive/ar/format.rb', line 5

def read_global_header(io)
  io.read(8).tap do |global_header|
    raise "Invalid header" unless global_header == Archive::Ar::MAGIC
  end
end

.read_header(io) ⇒ Object



46
47
48
49
50
51
52
53
54
55
56
57
58
# File 'lib/archive/ar/format.rb', line 46

def read_header(io)
  block = io.read(60)
  header = parse_header(block)
  header.merge! :start => io.tell

  if header[:name].start_with? "#1/"
    long_size = header[:name][3..-1].to_i
    header[:start] += long_size
    header[:name] = io.read(long_size).strip
  end

  header
end