709: def extract_entry(destdir, entry)
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
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
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