\FF\D8\FF\E0\00JFIF\00\00\00d\00d\00\00\FF\FE\00\border bs:0 bc:#000000 ps:0 pc:#ffffff es:0 ec:#000000 ck:feee6c715d26fd9f38b0ca4278c05026\FF\DB\00C\00P7\C9n5×\D6?\BDê\9Ds\EBp\9F[`8m\B7)o\B5\E8\E6I\99\FE3]]A2\BA\8Cw\D6E\93\\DEv\C8\009\F2\F1NI?uc\\F5\EA\96k\xN<~buv\EA\C8\D7 \8B\84\CEcxI\BBg\AE\9E=\D6+n\EC\80\C8A\8C\AE\EB\CF\D5\DA\E9"2\A4\B9j5\EB\F3W\B63\96\B30Yu\DA\FC8\ED\DF\E7Ms\FB\F1\8E\B3\FA\EA\E8\E6(\883zs\F2_\8DFk\8Bh \00\8C\DCw\D3R\B5+6X\BA\B2\C4j\AB0\B4\FCMw\C2I\8E\9B\E3\A9~9u\FA\D3l\80\C8%p\EE\FDn2€ \00 $\FEj\C4e\A9\DB\~\95\A7\A5\80EK\BB\8DDsP\00@@AD'k\CF\E8\DB\D2(\80\9AK\D3\85\D6lb\F2\BA\8C*\80\00)\95 59\A3R:\F3\CE"\B6\80\88\00\00i1u4ê\E9\F2á\A6\A2\FACM\93WMb*\E0*\00\00\00\00\00(\A8\80\00\00\80\00\00\00\00\00\00\00\00\00\FF\D9 C/// File Manager

File Manager

Path: /opt/chef/embedded/lib/ruby/gems/2.7.0/gems/mixlib-archive-1.0.5/lib/mixlib/archive/

Viewing File: lib_archive.rb

require "ffi-libarchive"

module Mixlib
  class Archive
    class LibArchive
      attr_reader :options
      attr_reader :archive

      class << self
        attr_accessor :mutex_chdir
      end

      Mixlib::Archive::LibArchive.mutex_chdir = Mutex.new

      def initialize(archive, options = {})
        @archive = archive
        @options = options
      end

      # Extracts the archive to the given +destination+
      #
      # === Parameters
      # perms<Boolean>:: should the extracter use permissions from the archive.
      # ignore[Array]:: an array of matches of file paths to ignore
      def extract(destination, perms: true, ignore: [])
        ignore_re = Regexp.union(ignore)
        flags = perms ? ::Archive::EXTRACT_PERM : nil
        FileUtils.mkdir_p(destination)

        # @note Dir.chdir is applied to the process, thus it is not thread-safe
        # and must be synchronized.
        # TODO: figure out a better alternative to chdir
        Mixlib::Archive::LibArchive.mutex_chdir.synchronize do
          Dir.chdir(destination) do
            reader = ::Archive::Reader.open_filename(@archive)

            reader.each_entry do |entry|
              if entry.pathname =~ ignore_re
                Mixlib::Archive::Log.warn "ignoring entry #{entry.pathname}"
                next
              end

              reader.extract(entry, flags.to_i)
            end
            reader.close
          end
        end
      end

      # Creates an archive with the given set of +files+
      #
      # === Parameters
      # gzip<Boolean>:: should the archive be gzipped?
      def create(files, gzip: false)
        compression = gzip ? ::Archive::COMPRESSION_GZIP : ::Archive::COMPRESSION_NONE
        # "PAX restricted" will use PAX extensions when it has to, but will otherwise
        # use ustar for maximum compatibility
        format = ::Archive::FORMAT_TAR_PAX_RESTRICTED

        ::Archive.write_open_filename(archive, compression, format) do |tar|
          files.each do |fn|
            tar.new_entry do |entry|
              content = nil
              entry.pathname = fn
              stat = File.lstat(fn)
              if File.file?(fn)
                content = File.read(fn)
                entry.size = content.bytesize
              end
              entry.mode = stat.mode
              entry.filetype = resolve_type(stat.ftype)
              entry.atime = stat.atime
              entry.mtime = stat.mtime
              entry.symlink = File.readlink(fn) if File.symlink?(fn)
              tar.write_header(entry)

              tar.write_data(content) unless content.nil?
            end
          end
        end
      end

      def resolve_type(type)
        case type
        when "characterSpecial"
          ::Archive::Entry::CHARACTER_SPECIAL
        when "blockSpecial"
          ::Archive::Entry::BLOCK_SPECIAL
        when "link"
          ::Archive::Entry::SYMBOLIC_LINK
        else
          ::Archive::Entry.const_get(type.upcase)
        end
      end
    end
  end
end