module Ronin::Support::Archive::Tar

Handles tar archive reading/writing.

## Examples

Create a tar reader stream around an existing IO object:

Tar.new(io) do |tar|
  file = tar['file.txt']
  puts "#{file.full_name} (#{file.header.umode})"
  puts file.read
end

Opening a tar writer stream around an existing IO object:

Tar.new(io, mode: 'w') do |tar|
  # add a file
  tar.add_file('file1.txt', "...")

  # add a file and open an output stream
  tar.add_file('file2.txt') do |io|
    io.write("...")
  end

  # add a symlink 'link' pointing to 'file1.txt'
  tar.add_symlink('link','file1.txt')

  # add a directory
  tar.mkdir('foo')
end

Opening

@api public

@since 1.0.0

Public Class Methods

new(io, mode: 'r', &block) click to toggle source

Creates a tar stream around the IO object.

@param [IO, StringIO, String] io

The IO object to read or write data to.

@param [String] mode

The mode to open the tar stream with.

@yield [tar]

If a block is given, it will be passed the tar stream object.

@yieldparam [Reader, Writer] tar

The tar reader or writer object.

@return [Reader, Writer]

The gzip reader or writer object.

@raise [ArgumentError]

The mode must include either `r`, `w`, or `a`.

@example Creates a tar reader stream around an existing IO object:

Tar.new(io) do |tar|
  # ...
end

@example Creates a tar writer stream around an existing IO object:

Tar.new(io, mode: 'w') do |tar|
  # ...
end

@api public

# File lib/ronin/support/archive/tar.rb, line 96
def self.new(io, mode: 'r', &block)
  tar_class = if mode.include?('w') || mode.include?('a')
                Writer
              elsif mode.include?('r')
                Reader
              else
                raise(ArgumentError,"mode argument must include either 'r', 'w', or 'a': #{mode.inspect}")
              end

  return tar_class.new(io, mode: mode, &block)
end
open(path, mode: 'r', &block) click to toggle source

Opens the tar file for reading or writing.

@param [String] path

The path to the tar file.

@param [String] mode

The mode to open the file as.

@yield [gz]

If a block is given, it will be passed the gzip writer object.

@yieldparam [Reader, Writer] tar

The tar writer object.

@return [Reader, Writer]

The tar writer object.

@raise [ArgumentError]

The mode must include either `r`, `w`, or `a`.

@example Open a tar file for reading:

Tar.open(path) do |tar|
  # ...
end

@example Open a tar file for writing:

Tar.open(path, mode: 'w') do |tar|
  # ...
end

@api public

# File lib/ronin/support/archive/tar.rb, line 141
def self.open(path, mode: 'r', &block)
  tar_class = if mode.include?('w') || mode.include?('a')
                Writer
              elsif mode.include?('r')
                Reader
              else
                raise(ArgumentError,"mode argument must include either 'r', 'w', or 'a': #{mode.inspect}")
              end

  return tar_class.open(path,&block)
end