????JFIF??x?x????'
| Server IP : 104.21.30.238  /  Your IP : 216.73.216.83 Web Server : LiteSpeed System : Linux premium151.web-hosting.com 4.18.0-553.44.1.lve.el8.x86_64 #1 SMP Thu Mar 13 14:29:12 UTC 2025 x86_64 User : tempvsty ( 647) PHP Version : 8.0.30 Disable Function : NONE MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : ON | Sudo : OFF | Pkexec : OFF Directory : /proc/thread-self/./root/opt/alt/ruby21/lib64/ruby/2.1.0/rubygems/package/ | 
| Upload File : | 
# -*- coding: utf-8 -*-
#--
# Copyright (C) 2004 Mauricio Julio Fernández Pradier
# See LICENSE.txt for additional licensing information.
#++
require 'digest'
##
# Allows writing of tar files
class Gem::Package::TarWriter
  class FileOverflow < StandardError; end
  ##
  # IO wrapper that allows writing a limited amount of data
  class BoundedStream
    ##
    # Maximum number of bytes that can be written
    attr_reader :limit
    ##
    # Number of bytes written
    attr_reader :written
    ##
    # Wraps +io+ and allows up to +limit+ bytes to be written
    def initialize(io, limit)
      @io = io
      @limit = limit
      @written = 0
    end
    ##
    # Writes +data+ onto the IO, raising a FileOverflow exception if the
    # number of bytes will be more than #limit
    def write(data)
      if data.bytesize + @written > @limit
        raise FileOverflow, "You tried to feed more data than fits in the file."
      end
      @io.write data
      @written += data.bytesize
      data.bytesize
    end
  end
  ##
  # IO wrapper that provides only #write
  class RestrictedStream
    ##
    # Creates a new RestrictedStream wrapping +io+
    def initialize(io)
      @io = io
    end
    ##
    # Writes +data+ onto the IO
    def write(data)
      @io.write data
    end
  end
  ##
  # Creates a new TarWriter, yielding it if a block is given
  def self.new(io)
    writer = super
    return writer unless block_given?
    begin
      yield writer
    ensure
      writer.close
    end
    nil
  end
  ##
  # Creates a new TarWriter that will write to +io+
  def initialize(io)
    @io = io
    @closed = false
  end
  ##
  # Adds file +name+ with permissions +mode+, and yields an IO for writing the
  # file to
  def add_file(name, mode) # :yields: io
    check_closed
    raise Gem::Package::NonSeekableIO unless @io.respond_to? :pos=
    name, prefix = split_name name
    init_pos = @io.pos
    @io.write "\0" * 512 # placeholder for the header
    yield RestrictedStream.new(@io) if block_given?
    size = @io.pos - init_pos - 512
    remainder = (512 - (size % 512)) % 512
    @io.write "\0" * remainder
    final_pos = @io.pos
    @io.pos = init_pos
    header = Gem::Package::TarHeader.new :name => name, :mode => mode,
                                         :size => size, :prefix => prefix,
                                         :mtime => Time.now
    @io.write header
    @io.pos = final_pos
    self
  end
  ##
  # Adds +name+ with permissions +mode+ to the tar, yielding +io+ for writing
  # the file.  The +digest_algorithm+ is written to a read-only +name+.sum
  # file following the given file contents containing the digest name and
  # hexdigest separated by a tab.
  #
  # The created digest object is returned.
  def add_file_digest name, mode, digest_algorithms # :yields: io
    digests = digest_algorithms.map do |digest_algorithm|
      digest = digest_algorithm.new
      digest_name =
        if digest.respond_to? :name then
          digest.name
        else
          /::([^:]+)$/ =~ digest_algorithm.name
          $1
        end
      [digest_name, digest]
    end
    digests = Hash[*digests.flatten]
    add_file name, mode do |io|
      Gem::Package::DigestIO.wrap io, digests do |digest_io|
        yield digest_io
      end
    end
    digests
  end
  ##
  # Adds +name+ with permissions +mode+ to the tar, yielding +io+ for writing
  # the file.  The +signer+ is used to add a digest file using its
  # digest_algorithm per add_file_digest and a cryptographic signature in
  # +name+.sig.  If the signer has no key only the checksum file is added.
  #
  # Returns the digest.
  def add_file_signed name, mode, signer
    digest_algorithms = [
      signer.digest_algorithm,
      Digest::SHA512,
    ].compact.uniq
    digests = add_file_digest name, mode, digest_algorithms do |io|
      yield io
    end
    signature_digest = digests.values.compact.find do |digest|
      digest_name =
        if digest.respond_to? :name then
          digest.name
        else
          /::([^:]+)$/ =~ digest.class.name
          $1
        end
      digest_name == signer.digest_name
    end
    if signer.key then
      signature = signer.sign signature_digest.digest
      add_file_simple "#{name}.sig", 0444, signature.length do |io|
        io.write signature
      end
    end
    digests
  end
  ##
  # Add file +name+ with permissions +mode+ +size+ bytes long.  Yields an IO
  # to write the file to.
  def add_file_simple(name, mode, size) # :yields: io
    check_closed
    name, prefix = split_name name
    header = Gem::Package::TarHeader.new(:name => name, :mode => mode,
                                         :size => size, :prefix => prefix,
                                         :mtime => Time.now).to_s
    @io.write header
    os = BoundedStream.new @io, size
    yield os if block_given?
    min_padding = size - os.written
    @io.write("\0" * min_padding)
    remainder = (512 - (size % 512)) % 512
    @io.write("\0" * remainder)
    self
  end
  ##
  # Raises IOError if the TarWriter is closed
  def check_closed
    raise IOError, "closed #{self.class}" if closed?
  end
  ##
  # Closes the TarWriter
  def close
    check_closed
    @io.write "\0" * 1024
    flush
    @closed = true
  end
  ##
  # Is the TarWriter closed?
  def closed?
    @closed
  end
  ##
  # Flushes the TarWriter's IO
  def flush
    check_closed
    @io.flush if @io.respond_to? :flush
  end
  ##
  # Creates a new directory in the tar file +name+ with +mode+
  def mkdir(name, mode)
    check_closed
    name, prefix = split_name(name)
    header = Gem::Package::TarHeader.new :name => name, :mode => mode,
                                         :typeflag => "5", :size => 0,
                                         :prefix => prefix,
                                         :mtime => Time.now
    @io.write header
    self
  end
  ##
  # Splits +name+ into a name and prefix that can fit in the TarHeader
  def split_name(name) # :nodoc:
    raise Gem::Package::TooLongFileName if name.bytesize > 256
    if name.bytesize <= 100 then
      prefix = ""
    else
      parts = name.split(/\//)
      newname = parts.pop
      nxt = ""
      loop do
        nxt = parts.pop
        break if newname.bytesize + 1 + nxt.bytesize > 100
        newname = nxt + "/" + newname
      end
      prefix = (parts + [nxt]).join "/"
      name = newname
      if name.bytesize > 100 or prefix.bytesize > 155 then
        raise Gem::Package::TooLongFileName
      end
    end
    return name, prefix
  end
end