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