/usr/lib/ruby/vendor_ruby/net/sftp/operations/file.rb is in ruby-net-sftp 1:2.1.2-4.
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 | require 'net/ssh/loggable'
module Net; module SFTP; module Operations
# A wrapper around an SFTP file handle, that exposes an IO-like interface
# for interacting with the remote file. All operations are synchronous
# (blocking), making this a very convenient way to deal with remote files.
#
# A wrapper is usually created via the Net::SFTP::Session#file factory:
#
# file = sftp.file.open("/path/to/remote")
# puts file.gets
# file.close
class File
# A reference to the Net::SFTP::Session instance that drives this wrapper
attr_reader :sftp
# The SFTP file handle object that this object wraps
attr_reader :handle
# The current position within the remote file
attr_reader :pos
# Creates a new wrapper that encapsulates the given +handle+ (such as
# would be returned by Net::SFTP::Session#open!). The +sftp+ parameter
# must be the same Net::SFTP::Session instance that opened the file.
def initialize(sftp, handle)
@sftp = sftp
@handle = handle
@pos = 0
@real_pos = 0
@real_eof = false
@buffer = ""
end
# Repositions the file pointer to the given offset (relative to the
# start of the file). This will also reset the EOF flag.
def pos=(offset)
@real_pos = @pos = offset
@buffer = ""
@real_eof = false
end
# Closes the underlying file and sets the handle to +nil+. Subsequent
# operations on this object will fail.
def close
sftp.close!(handle)
@handle = nil
end
# Returns true if the end of the file has been encountered by a previous
# read. Setting the current file position via #pos= will reset this
# flag (useful if the file's contents have changed since the EOF was
# encountered).
def eof?
@real_eof && @buffer.empty?
end
# Reads up to +n+ bytes of data from the stream. Fewer bytes will be
# returned if EOF is encountered before the requested number of bytes
# could be read. Without an argument (or with a nil argument) all data
# to the end of the file will be read and returned.
#
# This will advance the file pointer (#pos).
def read(n=nil)
loop do
break if n && @buffer.length >= n
break unless fill
end
if n
result, @buffer = @buffer[0,n], (@buffer[n..-1] || "")
else
result, @buffer = @buffer, ""
end
@pos += result.length
return result
end
# Reads up to the next instance of +sep_string+ in the stream, and
# returns the bytes read (including +sep_string+). If +sep_string+ is
# omitted, it defaults to +$/+. If EOF is encountered before any data
# could be read, #gets will return +nil+.
def gets(sep_string=$/)
delim = if sep_string.length == 0
"#{$/}#{$/}"
else
sep_string
end
loop do
at = @buffer.index(delim)
if at
offset = at + delim.length
@pos += offset
line, @buffer = @buffer[0,offset], @buffer[offset..-1]
return line
elsif !fill
return nil if @buffer.empty?
@pos += @buffer.length
line, @buffer = @buffer, ""
return line
end
end
end
# Same as #gets, but raises EOFError if EOF is encountered before any
# data could be read.
def readline(sep_string=$/)
line = gets(sep_string)
raise EOFError if line.nil?
return line
end
# Writes the given data to the stream, incrementing the file position and
# returning the number of bytes written.
def write(data)
data = data.to_s
sftp.write!(handle, @real_pos, data)
@real_pos += data.length
@pos = @real_pos
data.length
end
# Writes each argument to the stream. If +$\+ is set, it will be written
# after all arguments have been written.
def print(*items)
items.each { |item| write(item) }
write($\) if $\
nil
end
# Writes each argument to the stream, appending a newline to any item
# that does not already end in a newline. Array arguments are flattened.
def puts(*items)
items.each do |item|
if Array === item
puts(*item)
else
write(item)
write("\n") unless item[-1] == ?\n
end
end
nil
end
# Performs an fstat operation on the handle and returns the attribute
# object (Net::SFTP::Protocol::V01::Attributes, Net::SFTP::Protool::V04::Attributes,
# or Net::SFTP::Protocol::V06::Attributes, depending on the SFTP protocol
# version in use).
def stat
sftp.fstat!(handle)
end
private
# Fills the buffer. Returns +true+ if it succeeded, and +false+ if
# EOF was encountered before any data was read.
def fill
data = sftp.read!(handle, @real_pos, 8192)
if data.nil?
@real_eof = true
return false
else
@real_pos += data.length
@buffer << data
end
!@real_eof
end
end
end; end; end
|