class Archive::Tar::Minitar::Input

Wraps a Archive::Tar::Minitar::Reader with convenience methods and wrapped stream management; Input only works with random access data streams. See Input::new for details.

Public Class Methods

new(input) click to toggle source

Creates a new Input object. If input is a stream object that responds to read), then it will simply be wrapped. Otherwise, one will be created and opened using Kernel#open. When Input#close is called, the stream object wrapped will be closed.

    # File lib/archive/tar/minitar.rb
667 def initialize(input)
668   if input.respond_to?(:read)
669     @io = input
670   else
671     @io = open(input, "rb")
672   end
673   @tarreader = Archive::Tar::Minitar::Reader.new(@io)
674 end
open(input) { |stream| ... } click to toggle source

With no associated block, Input::open is a synonym for Input::new. If the optional code block is given, it will be passed the new writer as an argument and the Input object will automatically be closed when the block terminates. In this instance, Input::open returns the value of the block.

    # File lib/archive/tar/minitar.rb
650 def self.open(input)
651   stream = Input.new(input)
652   return stream unless block_given?
653 
654   begin
655     res = yield stream
656   ensure
657     stream.close
658   end
659 
660   res
661 end

Public Instance Methods

close() click to toggle source

Closes the Reader object and the wrapped data stream.

    # File lib/archive/tar/minitar.rb
765 def close
766   @io.close
767   @tarreader.close
768 end
each() { |entry| ... } click to toggle source

Iterates through each entry and rewinds to the beginning of the stream when finished.

    # File lib/archive/tar/minitar.rb
678 def each(&block)
679   @tarreader.each { |entry| yield entry }
680 ensure
681   @tarreader.rewind
682 end
extract_entry(destdir, entry) { |:dir, full_name, stats| ... } click to toggle source

Extracts the current entry to destdir. If a block is provided, it yields an action Symbol, the full name of the file being extracted (name), and a Hash of statistical information (stats).

The action will be one of:

:dir

The entry is a directory.

:file_start

The entry is a file; the extract of the file is just beginning.

:file_progress

Yielded every 4096 bytes during the extract of the entry.

:file_done

Yielded when the entry is completed.

The stats hash contains the following keys:

:current

The current total number of bytes read in the entry.

:currinc

The current number of bytes read in this read cycle.

:entry

The entry being extracted; this is a Reader::EntryStream, with all methods thereof.

    # File lib/archive/tar/minitar.rb
703 def extract_entry(destdir, entry) # :yields action, name, stats:
704   stats = {
705     :current  => 0,
706     :currinc  => 0,
707     :entry    => entry
708   }
709 
710   if entry.directory?
711     dest = File.join(destdir, entry.full_name)
712 
713     yield :dir, entry.full_name, stats if block_given?
714 
715     if Archive::Tar::Minitar.dir?(dest)
716       begin
717         FileUtils.chmod(entry.mode, dest)
718       rescue Exception
719         nil
720       end
721     else
722       FileUtils.mkdir_p(dest, :mode => entry.mode)
723       FileUtils.chmod(entry.mode, dest)
724     end
725 
726     fsync_dir(dest)
727     fsync_dir(File.join(dest, ".."))
728     return
729   else # it's a file
730     destdir = File.join(destdir, File.dirname(entry.full_name))
731     FileUtils.mkdir_p(destdir, :mode => 0755)
732 
733     destfile = File.join(destdir, File.basename(entry.full_name))
734     FileUtils.chmod(0600, destfile) rescue nil  # Errno::ENOENT
735 
736     yield :file_start, entry.full_name, stats if block_given?
737 
738     File.open(destfile, "wb", entry.mode) do |os|
739       loop do
740         data = entry.read(4096)
741         break unless data
742 
743         stats[:currinc] = os.write(data)
744         stats[:current] += stats[:currinc]
745 
746         yield :file_progress, entry.full_name, stats if block_given?
747       end
748       os.fsync
749     end
750 
751     FileUtils.chmod(entry.mode, destfile)
752     fsync_dir(File.dirname(destfile))
753     fsync_dir(File.join(File.dirname(destfile), ".."))
754 
755     yield :file_done, entry.full_name, stats if block_given?
756   end
757 end
tar() click to toggle source

Returns the Reader object for direct access.

    # File lib/archive/tar/minitar.rb
760 def tar
761   @tarreader
762 end

Private Instance Methods

fsync_dir(dirname) click to toggle source
    # File lib/archive/tar/minitar.rb
771 def fsync_dir(dirname)
772     # make sure this hits the disc
773   dir = open(dirname, 'rb')
774   dir.fsync
775 rescue # ignore IOError if it's an unpatched (old) Ruby
776   nil
777 ensure
778   dir.close if dir rescue nil
779 end