diff options
Diffstat (limited to 'ruby_2_2/lib/rubygems/package/tar_writer.rb')
-rw-r--r-- | ruby_2_2/lib/rubygems/package/tar_writer.rb | 326 |
1 files changed, 0 insertions, 326 deletions
diff --git a/ruby_2_2/lib/rubygems/package/tar_writer.rb b/ruby_2_2/lib/rubygems/package/tar_writer.rb deleted file mode 100644 index dfd635724b..0000000000 --- a/ruby_2_2/lib/rubygems/package/tar_writer.rb +++ /dev/null @@ -1,326 +0,0 @@ -# -*- 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: - if name.bytesize > 256 - raise Gem::Package::TooLongFileName.new("File \"#{name}\" has a too long path (should be 256 or less)") - end - - 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 - raise Gem::Package::TooLongFileName.new("File \"#{prefix}/#{name}\" has a too long name (should be 100 or less)") - end - - if prefix.bytesize > 155 then - raise Gem::Package::TooLongFileName.new("File \"#{prefix}/#{name}\" has a too long base path (should be 155 or less)") - end - end - - return name, prefix - end - -end - |