This file is indexed.

/usr/lib/ruby/vendor_ruby/net/ssh/buffered_io.rb is in ruby-net-ssh 1:3.2.0-1.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
require 'net/ssh/buffer'
require 'net/ssh/loggable'
require 'net/ssh/ruby_compat'

module Net; module SSH

  # This module is used to extend sockets and other IO objects, to allow
  # them to be buffered for both read and write. This abstraction makes it
  # quite easy to write a select-based event loop
  # (see Net::SSH::Connection::Session#listen_to).
  #
  # The general idea is that instead of calling #read directly on an IO that
  # has been extended with this module, you call #fill (to add pending input
  # to the internal read buffer), and then #read_available (to read from that
  # buffer). Likewise, you don't call #write directly, you call #enqueue to
  # add data to the write buffer, and then #send_pending or #wait_for_pending_sends
  # to actually send the data across the wire.
  #
  # In this way you can easily use the object as an argument to IO.select,
  # calling #fill when it is available for read, or #send_pending when it is
  # available for write, and then call #enqueue and #read_available during
  # the idle times.
  #
  #   socket = TCPSocket.new(address, port)
  #   socket.extend(Net::SSH::BufferedIo)
  #
  #   ssh.listen_to(socket)
  #
  #   ssh.loop do
  #     if socket.available > 0
  #       puts socket.read_available
  #       socket.enqueue("response\n")
  #     end
  #   end
  #
  # Note that this module must be used to extend an instance, and should not
  # be included in a class. If you do want to use it via an include, then you
  # must make sure to invoke the private #initialize_buffered_io method in
  # your class' #initialize method:
  #
  #   class Foo < IO
  #     include Net::SSH::BufferedIo
  #
  #     def initialize
  #       initialize_buffered_io
  #       # ...
  #     end
  #   end
  module BufferedIo
    include Loggable

    # Called when the #extend is called on an object, with this module as the
    # argument. It ensures that the modules instance variables are all properly
    # initialized.
    def self.extended(object) #:nodoc:
      # need to use __send__ because #send is overridden in Socket
      object.__send__(:initialize_buffered_io)
    end

    # Tries to read up to +n+ bytes of data from the remote end, and appends
    # the data to the input buffer. It returns the number of bytes read, or 0
    # if no data was available to be read.
    def fill(n=8192)
      input.consume!
      data = recv(n)
      debug { "read #{data.length} bytes" }
      input.append(data)
      return data.length
    end

    # Read up to +length+ bytes from the input buffer. If +length+ is nil,
    # all available data is read from the buffer. (See #available.)
    def read_available(length=nil)
      input.read(length || available)
    end

    # Returns the number of bytes available to be read from the input buffer.
    # (See #read_available.)
    def available
      input.available
    end

    # Enqueues data in the output buffer, to be written when #send_pending
    # is called. Note that the data is _not_ sent immediately by this method!
    def enqueue(data)
      output.append(data)
    end

    # Returns +true+ if there is data waiting in the output buffer, and
    # +false+ otherwise.
    def pending_write?
      output.length > 0
    end

    # Sends as much of the pending output as possible. Returns +true+ if any
    # data was sent, and +false+ otherwise.
    def send_pending
      if output.length > 0
        sent = send(output.to_s, 0)
        debug { "sent #{sent} bytes" }
        output.consume!(sent)
        return sent > 0
      else
        return false
      end
    end

    # Calls #send_pending repeatedly, if necessary, blocking until the output
    # buffer is empty.
    def wait_for_pending_sends
      send_pending
      while output.length > 0
        result = Net::SSH::Compat.io_select(nil, [self]) or next
        next unless result[1].any?
        send_pending
      end
    end

    public # these methods are primarily for use in tests

      def write_buffer #:nodoc:
        output.to_s
      end

      def read_buffer #:nodoc:
        input.to_s
      end

    private

      #--
      # Can't use attr_reader here (after +private+) without incurring the
      # wrath of "ruby -w". We hates it.
      #++

      def input; @input; end
      def output; @output; end

      # Initializes the intput and output buffers for this object. This method
      # is called automatically when the module is mixed into an object via
      # Object#extend (see Net::SSH::BufferedIo.extended), but must be called
      # explicitly in the +initialize+ method of any class that uses
      # Module#include to add this module.
      def initialize_buffered_io
        @input = Net::SSH::Buffer.new
        @output = Net::SSH::Buffer.new
      end
  end


  
  # Fixes for two issues by Miklós Fazekas:
  #
  #   * if client closes a forwarded connection, but the server is 
  #     reading, net-ssh terminates with IOError socket closed.
  #   * if client force closes (RST) a forwarded connection, but 
  #     server is reading, net-ssh terminates with [an exception]
  #
  # See: 
  # 
  #    http://net-ssh.lighthouseapp.com/projects/36253/tickets/7
  #    http://github.com/net-ssh/net-ssh/tree/portfwfix
  #
  module ForwardedBufferedIo
    def fill(n=8192)
      begin
        super(n)
      rescue Errno::ECONNRESET => e
        debug { "connection was reset => shallowing exception:#{e}" }
        return 0
      rescue IOError => e                                 
        if e.message =~ /closed/ then 
          debug { "connection was reset => shallowing exception:#{e}" }
          return 0
        else
          raise
        end 
      end
    end
    
    def send_pending
      begin
        super                                                          
      rescue Errno::ECONNRESET => e
        debug { "connection was reset => shallowing exception:#{e}" }
        return 0
      rescue IOError => e
        if e.message =~ /closed/ then 
          debug { "connection was reset => shallowing exception:#{e}" }
          return 0
        else
          raise
        end
      end
    end
  end
  
end; end