The implementing class for version 1 of the SFTP protocol. It implements the various operations and callbacks available to this level of the protocol. Other protocol versions will typically extend this class, adding (or modifying) methods as needed to bring the implementation into sync with the needed version.
Name | = | Struct.new( :filename, :longname, :attributes ) |
F_READ | = | 0x00000001 |
F_WRITE | = | 0x00000002 |
F_APPEND | = | 0x00000004 |
F_CREAT | = | 0x00000008 |
F_TRUNC | = | 0x00000010 |
F_EXCL | = | 0x00000020 |
[R] | attr_factory | The attribute-factory used by this dispatcher. |
[R] | driver | The protocol driver that drives this dispatcher. |
[RW] | extensions | The protocol extensions specified when the protocol version was negotiated. |
A helper method for registering new callbacks. Each callback will cause three new methods to be created, on_name, has_on_name?, and call_on_name. The on_name method may be used to register a block for the corresponding callback.
[ show source ]
# File lib/net/sftp/protocol/01/impl.rb, line 80 80: def self.callback( *names ) 81: names.each do |name| 82: class_eval "def on_\#{name}( &block )\n@on_\#{name} = block\nend\n\ndef has_on_\#{name}?\nnot @on_\#{name}.nil?\nend\n\ndef call_on_\#{name}( *args )\nreturn unless @on_\#{name}\n@on_\#{name}.call( *args )\nend\n\npublic :on_\#{name}\nprotected :has_on_\#{name}?, :call_on_\#{name}\n", __FILE__, __LINE__+1 83: end 84: end
Create a new instance using the given protocol driver, packet assistant, and attributes factory.
[ show source ]
# File lib/net/sftp/protocol/01/impl.rb, line 44 44: def initialize( buffers, driver, assistant, attr_factory ) 45: @buffers = buffers 46: @driver = driver 47: @assistant = assistant 48: @attr_factory = attr_factory 49: @on_status = nil 50: @on_handle = nil 51: @on_data = nil 52: @on_name = nil 53: @on_attrs = nil 54: end
A helper method for defining new operations supported by this implementation. This will create one method for each named operation. By default, the method simply formats the packet (using the packet assistant), and then sends the data via the driver. It will then return the request id used for this operation.
[ show source ]
# File lib/net/sftp/protocol/01/impl.rb, line 61 61: def self.operation( *names ) 62: names.each do |name| 63: const = "FXP_#{name.to_s.upcase}" 64: class_eval "def \#{name}( id, *args )\nid, packet = @assistant.\#{name}( id, *args )\n@driver.send_data \#{const}, packet\nid\nend\n", __FILE__, __LINE__+1 65: end 66: end
Dispatches the given packet type to the appropriate handler method. If a new protocol version adds a new packet type, it should override this method, performing its own checking first, followed by calling super.
[ show source ]
# File lib/net/sftp/protocol/01/impl.rb, line 189 189: def dispatch( channel, type, content ) 190: case type 191: when FXP_STATUS then do_status( channel, content ) 192: when FXP_HANDLE then do_handle( channel, content ) 193: when FXP_DATA then do_data( channel, content ) 194: when FXP_NAME then do_name( channel, content ) 195: when FXP_ATTRS then do_attrs( channel, content ) 196: else 197: raise Net::SFTP::Exception, 198: "unsupported SFTP packet type #{type} (#{content.to_s.inspect})" 199: end 200: end
Used internally to handle attrs packets. The on_attrs callback is invoked, if registered, with the driver, id, and attribute object.
[ show source ]
# File lib/net/sftp/protocol/01/impl.rb, line 244 244: def do_attrs( channel, content ) 245: return unless has_on_attrs? 246: id = content.read_long 247: attrs = @attr_factory.from_buffer( content ) 248: call_on_attrs( driver, id, attrs ) 249: end
Used internally to handle data packets. The on_data callback is invoked, if registered, with the driver, id, and data (as a buffer).
[ show source ]
# File lib/net/sftp/protocol/01/impl.rb, line 222 222: def do_data( channel, content ) 223: return unless has_on_data? 224: id = content.read_long 225: data = content.read_string 226: call_on_data( driver, id, data ) 227: end
Used internally to handle handle packets. The on_handle callback is invoked, if registered, with the driver, id, and handle.
[ show source ]
# File lib/net/sftp/protocol/01/impl.rb, line 213 213: def do_handle( channel, content ) 214: return unless has_on_handle? 215: id = content.read_long 216: handle = content.read_string 217: call_on_handle( driver, id, handle ) 218: end
Used internally to handle name packets. The on_name callback is invoked, if registered, with the driver, id, and array of items.
[ show source ]
# File lib/net/sftp/protocol/01/impl.rb, line 231 231: def do_name( channel, content ) 232: return unless has_on_name? 233: id = content.read_long 234: items = [] 235: content.read_long.times do 236: items.push( Name.new( content.read_string, content.read_string, 237: @attr_factory.from_buffer( content ) ) ) 238: end 239: call_on_name( driver, id, items ) 240: end
Used internally to handle status packets. The on_status callback is invoked, if registered, with the driver, id, and code.
[ show source ]
# File lib/net/sftp/protocol/01/impl.rb, line 204 204: def do_status( channel, content ) 205: return unless has_on_status? 206: id = content.read_long 207: code = content.read_long 208: call_on_status( driver, id, code, nil, nil ) 209: end
The fstat operation is special, since later versions of the protocol add support for ‘flags’. These flags are ignored in this version, but the parameter exists to allow a program written for one version of the protocol to work with later versions.
[ show source ]
# File lib/net/sftp/protocol/01/impl.rb, line 181 181: def fstat( id, handle, flags=nil ) 182: fstat_raw id, handle 183: end
The lstat operation is special, since later versions of the protocol add support for ‘flags’. These flags are ignored in this version, but the parameter exists to allow a program written for one version of the protocol to work with later versions.
[ show source ]
# File lib/net/sftp/protocol/01/impl.rb, line 173 173: def lstat( id, filename, flags=nil ) 174: lstat_raw id, filename 175: end
The open operation is special, since it protects the caller from the specific flags and options required by SFTP. Instead, the caller simply specifies a combination of IO flags, and an appropriate posix mode, and they are translated into the correct SFTP flags.
[ show source ]
# File lib/net/sftp/protocol/01/impl.rb, line 143 143: def open( id, path, flags, mode=0660 ) 144: sftp_flags = case 145: when ( flags & IO::WRONLY ) != 0 then F_WRITE 146: when ( flags & IO::RDWR ) != 0 then F_READ | F_WRITE 147: when ( flags & IO::APPEND ) != 0 then F_APPEND 148: else F_READ 149: end 150: 151: sftp_flags |= F_CREAT if ( flags & IO::CREAT ) != 0 152: sftp_flags |= F_TRUNC if ( flags & IO::TRUNC ) != 0 153: sftp_flags |= F_EXCL if ( flags & IO::EXCL ) != 0 154: 155: attributes = @attr_factory.empty 156: attributes.permissions = mode 157: 158: open_raw id, path, sftp_flags, attributes 159: end
The stat operation is special, since later versions of the protocol add support for ‘flags’. These flags are ignored in this version, but the parameter exists to allow a program written for one version of the protocol to work with later versions.
[ show source ]
# File lib/net/sftp/protocol/01/impl.rb, line 165 165: def stat( id, filename, flags=nil ) 166: stat_raw id, filename 167: end