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
673 def initialize(input)
674   if input.respond_to?(:read)
675     @io = input
676   else
677     @io = open(input, "rb")
678   end
679   @tarreader = Archive::Tar::Minitar::Reader.new(@io)
680 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
656 def self.open(input)
657   stream = Input.new(input)
658   return stream unless block_given?
659 
660   begin
661     res = yield stream
662   ensure
663     stream.close
664   end
665 
666   res
667 end

Public Instance Methods

close() click to toggle source

Closes the Reader object and the wrapped data stream.

    # File lib/archive/tar/minitar.rb
771 def close
772   @io.close
773   @tarreader.close
774 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
684 def each(&block)
685   @tarreader.each { |entry| yield entry }
686 ensure
687   @tarreader.rewind
688 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
709 def extract_entry(destdir, entry) # :yields action, name, stats:
710   stats = {
711     :current  => 0,
712     :currinc  => 0,
713     :entry    => entry
714   }
715 
716   if entry.directory?
717     dest = File.join(destdir, entry.full_name)
718 
719     yield :dir, entry.full_name, stats if block_given?
720 
721     if Archive::Tar::Minitar.dir?(dest)
722       begin
723         FileUtils.chmod(entry.mode, dest)
724       rescue Exception
725         nil
726       end
727     else
728       FileUtils.mkdir_p(dest, :mode => entry.mode)
729       FileUtils.chmod(entry.mode, dest)
730     end
731 
732     fsync_dir(dest)
733     fsync_dir(File.join(dest, ".."))
734     return
735   else # it's a file
736     destdir = File.join(destdir, File.dirname(entry.full_name))
737     FileUtils.mkdir_p(destdir, :mode => 0755)
738 
739     destfile = File.join(destdir, File.basename(entry.full_name))
740     FileUtils.chmod(0600, destfile) rescue nil  # Errno::ENOENT
741 
742     yield :file_start, entry.full_name, stats if block_given?
743 
744     File.open(destfile, "wb", entry.mode) do |os|
745       loop do
746         data = entry.read(4096)
747         break unless data
748 
749         stats[:currinc] = os.write(data)
750         stats[:current] += stats[:currinc]
751 
752         yield :file_progress, entry.full_name, stats if block_given?
753       end
754       os.fsync
755     end
756 
757     FileUtils.chmod(entry.mode, destfile)
758     fsync_dir(File.dirname(destfile))
759     fsync_dir(File.join(File.dirname(destfile), ".."))
760 
761     yield :file_done, entry.full_name, stats if block_given?
762   end
763 end
tar() click to toggle source

Returns the Reader object for direct access.

    # File lib/archive/tar/minitar.rb
766 def tar
767   @tarreader
768 end

Private Instance Methods

fsync_dir(dirname) click to toggle source
    # File lib/archive/tar/minitar.rb
777 def fsync_dir(dirname)
778     # make sure this hits the disc
779   dir = open(dirname, 'rb')
780   dir.fsync
781 rescue # ignore IOError if it's an unpatched (old) Ruby
782   nil
783 ensure
784   dir.close if dir rescue nil
785 end