hrr_rb_sftp 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +23 -0
- data/lib/hrr_rb_sftp.rb +79 -1
- data/lib/hrr_rb_sftp/loggable.rb +34 -0
- data/lib/hrr_rb_sftp/protocol.rb +39 -33
- data/lib/hrr_rb_sftp/protocol/common.rb +6 -3
- data/lib/hrr_rb_sftp/protocol/common/data_types.rb +19 -0
- data/lib/hrr_rb_sftp/protocol/common/data_types/byte.rb +40 -0
- data/lib/hrr_rb_sftp/protocol/common/data_types/extension_pair.rb +41 -0
- data/lib/hrr_rb_sftp/protocol/common/data_types/extension_pairs.rb +42 -0
- data/lib/hrr_rb_sftp/protocol/common/data_types/string.rb +42 -0
- data/lib/hrr_rb_sftp/protocol/common/data_types/uint32.rb +40 -0
- data/lib/hrr_rb_sftp/protocol/common/data_types/uint64.rb +40 -0
- data/lib/hrr_rb_sftp/protocol/common/packets.rb +16 -0
- data/lib/hrr_rb_sftp/protocol/common/packets/001_ssh_fxp_init.rb +27 -0
- data/lib/hrr_rb_sftp/protocol/common/packets/002_ssh_fxp_version.rb +28 -0
- data/lib/hrr_rb_sftp/protocol/common/packets/packet.rb +96 -0
- data/lib/hrr_rb_sftp/protocol/version1.rb +11 -3
- data/lib/hrr_rb_sftp/protocol/version1/data_types.rb +15 -0
- data/lib/hrr_rb_sftp/protocol/version1/data_types/attrs.rb +91 -0
- data/lib/hrr_rb_sftp/protocol/version1/packets.rb +72 -0
- data/lib/hrr_rb_sftp/protocol/version1/{packet → packets}/003_ssh_fxp_open.rb +94 -43
- data/lib/hrr_rb_sftp/protocol/version1/packets/004_ssh_fxp_close.rb +61 -0
- data/lib/hrr_rb_sftp/protocol/version1/packets/005_ssh_fxp_read.rb +72 -0
- data/lib/hrr_rb_sftp/protocol/version1/packets/006_ssh_fxp_write.rb +64 -0
- data/lib/hrr_rb_sftp/protocol/version1/{packet → packets}/007_ssh_fxp_lstat.rb +27 -9
- data/lib/hrr_rb_sftp/protocol/version1/{packet → packets}/008_ssh_fxp_fstat.rb +26 -9
- data/lib/hrr_rb_sftp/protocol/version1/packets/009_ssh_fxp_setstat.rb +92 -0
- data/lib/hrr_rb_sftp/protocol/version1/packets/010_ssh_fxp_fsetstat.rb +85 -0
- data/lib/hrr_rb_sftp/protocol/version1/{packet → packets}/011_ssh_fxp_opendir.rb +32 -11
- data/lib/hrr_rb_sftp/protocol/version1/{packet → packets}/012_ssh_fxp_readdir.rb +73 -49
- data/lib/hrr_rb_sftp/protocol/version1/{packet → packets}/013_ssh_fxp_remove.rb +27 -9
- data/lib/hrr_rb_sftp/protocol/version1/{packet → packets}/014_ssh_fxp_mkdir.rb +28 -10
- data/lib/hrr_rb_sftp/protocol/version1/{packet → packets}/015_ssh_fxp_rmdir.rb +32 -12
- data/lib/hrr_rb_sftp/protocol/version1/packets/016_ssh_fxp_realpath.rb +47 -0
- data/lib/hrr_rb_sftp/protocol/version1/{packet → packets}/017_ssh_fxp_stat.rb +27 -9
- data/lib/hrr_rb_sftp/protocol/version1/packets/101_ssh_fxp_status.rb +73 -0
- data/lib/hrr_rb_sftp/protocol/version1/packets/102_ssh_fxp_handle.rb +28 -0
- data/lib/hrr_rb_sftp/protocol/version1/packets/103_ssh_fxp_data.rb +28 -0
- data/lib/hrr_rb_sftp/protocol/version1/packets/104_ssh_fxp_name.rb +48 -0
- data/lib/hrr_rb_sftp/protocol/version1/packets/105_ssh_fxp_attrs.rb +28 -0
- data/lib/hrr_rb_sftp/protocol/version1/packets/packet.rb +57 -0
- data/lib/hrr_rb_sftp/protocol/version2.rb +11 -3
- data/lib/hrr_rb_sftp/protocol/version2/data_types.rb +13 -0
- data/lib/hrr_rb_sftp/protocol/version2/packets.rb +14 -0
- data/lib/hrr_rb_sftp/protocol/version2/packets/018_ssh_fxp_rename.rb +91 -0
- data/lib/hrr_rb_sftp/protocol/version3.rb +12 -3
- data/lib/hrr_rb_sftp/protocol/version3/data_types.rb +13 -0
- data/lib/hrr_rb_sftp/protocol/version3/extensions.rb +94 -0
- data/lib/hrr_rb_sftp/protocol/version3/extensions/extension.rb +58 -0
- data/lib/hrr_rb_sftp/protocol/version3/extensions/fsync_at_openssh_com.rb +59 -0
- data/lib/hrr_rb_sftp/protocol/version3/extensions/hardlink_at_openssh_com.rb +84 -0
- data/lib/hrr_rb_sftp/protocol/version3/extensions/lsetstat_at_openssh_com.rb +132 -0
- data/lib/hrr_rb_sftp/protocol/version3/extensions/posix_rename_at_openssh_com.rb +76 -0
- data/lib/hrr_rb_sftp/protocol/version3/packets.rb +19 -0
- data/lib/hrr_rb_sftp/protocol/version3/packets/014_ssh_fxp_mkdir.rb +75 -0
- data/lib/hrr_rb_sftp/protocol/version3/packets/019_ssh_fxp_readlink.rb +76 -0
- data/lib/hrr_rb_sftp/protocol/version3/packets/020_ssh_fxp_symlink.rb +76 -0
- data/lib/hrr_rb_sftp/protocol/version3/packets/101_ssh_fxp_status.rb +25 -0
- data/lib/hrr_rb_sftp/protocol/version3/packets/200_ssh_fxp_extended.rb +95 -0
- data/lib/hrr_rb_sftp/protocol/version3/packets/201_ssh_fxp_extended_reply.rb +60 -0
- data/lib/hrr_rb_sftp/receiver.rb +17 -2
- data/lib/hrr_rb_sftp/sender.rb +15 -1
- data/lib/hrr_rb_sftp/server.rb +43 -12
- data/lib/hrr_rb_sftp/version.rb +5 -1
- metadata +54 -47
- data/lib/hrr_rb_sftp/protocol/common/data_type.rb +0 -15
- data/lib/hrr_rb_sftp/protocol/common/data_type/byte.rb +0 -22
- data/lib/hrr_rb_sftp/protocol/common/data_type/extension_pair.rb +0 -23
- data/lib/hrr_rb_sftp/protocol/common/data_type/extension_pairs.rb +0 -24
- data/lib/hrr_rb_sftp/protocol/common/data_type/string.rb +0 -24
- data/lib/hrr_rb_sftp/protocol/common/data_type/uint32.rb +0 -22
- data/lib/hrr_rb_sftp/protocol/common/data_type/uint64.rb +0 -22
- data/lib/hrr_rb_sftp/protocol/common/packet.rb +0 -11
- data/lib/hrr_rb_sftp/protocol/common/packet/001_ssh_fxp_init.rb +0 -18
- data/lib/hrr_rb_sftp/protocol/common/packet/002_ssh_fxp_version.rb +0 -19
- data/lib/hrr_rb_sftp/protocol/common/packetable.rb +0 -72
- data/lib/hrr_rb_sftp/protocol/version1/data_type.rb +0 -11
- data/lib/hrr_rb_sftp/protocol/version1/data_type/attrs.rb +0 -54
- data/lib/hrr_rb_sftp/protocol/version1/packet.rb +0 -29
- data/lib/hrr_rb_sftp/protocol/version1/packet/004_ssh_fxp_close.rb +0 -44
- data/lib/hrr_rb_sftp/protocol/version1/packet/005_ssh_fxp_read.rb +0 -53
- data/lib/hrr_rb_sftp/protocol/version1/packet/006_ssh_fxp_write.rb +0 -46
- data/lib/hrr_rb_sftp/protocol/version1/packet/009_ssh_fxp_setstat.rb +0 -63
- data/lib/hrr_rb_sftp/protocol/version1/packet/010_ssh_fxp_fsetstat.rb +0 -48
- data/lib/hrr_rb_sftp/protocol/version1/packet/016_ssh_fxp_realpath.rb +0 -30
- data/lib/hrr_rb_sftp/protocol/version1/packet/101_ssh_fxp_status.rb +0 -29
- data/lib/hrr_rb_sftp/protocol/version1/packet/102_ssh_fxp_handle.rb +0 -19
- data/lib/hrr_rb_sftp/protocol/version1/packet/103_ssh_fxp_data.rb +0 -19
- data/lib/hrr_rb_sftp/protocol/version1/packet/104_ssh_fxp_name.rb +0 -33
- data/lib/hrr_rb_sftp/protocol/version1/packet/105_ssh_fxp_attrs.rb +0 -19
- data/lib/hrr_rb_sftp/protocol/version2/data_type.rb +0 -9
- data/lib/hrr_rb_sftp/protocol/version2/packet.rb +0 -11
- data/lib/hrr_rb_sftp/protocol/version2/packet/018_ssh_fxp_rename.rb +0 -70
- data/lib/hrr_rb_sftp/protocol/version3/data_type.rb +0 -9
- data/lib/hrr_rb_sftp/protocol/version3/packet.rb +0 -16
- data/lib/hrr_rb_sftp/protocol/version3/packet/014_ssh_fxp_mkdir.rb +0 -58
- data/lib/hrr_rb_sftp/protocol/version3/packet/019_ssh_fxp_readlink.rb +0 -57
- data/lib/hrr_rb_sftp/protocol/version3/packet/020_ssh_fxp_symlink.rb +0 -58
- data/lib/hrr_rb_sftp/protocol/version3/packet/101_ssh_fxp_status.rb +0 -31
- data/lib/hrr_rb_sftp/protocol/version3/packet/200_ssh_fxp_extended.rb +0 -34
- data/lib/hrr_rb_sftp/protocol/version3/packet/201_ssh_fxp_extended_reply.rb +0 -23
@@ -0,0 +1,57 @@
|
|
1
|
+
module HrrRbSftp
|
2
|
+
class Protocol
|
3
|
+
module Version1
|
4
|
+
class Packets
|
5
|
+
|
6
|
+
#
|
7
|
+
# This class implements base packet operations and is to be inherited by each packet class.
|
8
|
+
#
|
9
|
+
class Packet < Common::Packets::Packet
|
10
|
+
|
11
|
+
#
|
12
|
+
# Returns a new instance of a class that includes this module.
|
13
|
+
#
|
14
|
+
# @param context [Hash] Contextual variables.
|
15
|
+
# - :version (Integer) - Negotiated protocol version.
|
16
|
+
# - :handles (Hash\\{String=>File, Dir\}) - Opened handles.
|
17
|
+
# @param logger [Logger] Logger.
|
18
|
+
#
|
19
|
+
def initialize context, logger: nil
|
20
|
+
super logger: logger
|
21
|
+
|
22
|
+
@context = context
|
23
|
+
end
|
24
|
+
|
25
|
+
#
|
26
|
+
# Returns contextual variables.
|
27
|
+
#
|
28
|
+
# @return [Hash] Contextual variables.
|
29
|
+
# - :version (Integer) - Negotiated protocol version.
|
30
|
+
# - :handles (Hash\\{String=>File, Dir\}) - Opened handles.
|
31
|
+
#
|
32
|
+
def context
|
33
|
+
@context
|
34
|
+
end
|
35
|
+
|
36
|
+
#
|
37
|
+
# Returns Negotiated protocol version.
|
38
|
+
#
|
39
|
+
# @return [Integer] Negotiated protocol version.
|
40
|
+
#
|
41
|
+
def version
|
42
|
+
@context[:version]
|
43
|
+
end
|
44
|
+
|
45
|
+
#
|
46
|
+
# Returns opened handles.
|
47
|
+
#
|
48
|
+
# @return [Hash{String=>File, Dir}] Opened handles.
|
49
|
+
#
|
50
|
+
def handles
|
51
|
+
@context[:handles]
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -1,10 +1,18 @@
|
|
1
1
|
module HrrRbSftp
|
2
2
|
class Protocol
|
3
|
-
|
3
|
+
|
4
|
+
#
|
5
|
+
# This module implements SFTP protocol version 2 packet types, formats, and responders.
|
6
|
+
#
|
7
|
+
module Version2
|
8
|
+
|
9
|
+
#
|
10
|
+
# Represents SFTP protocol version 2.
|
11
|
+
#
|
4
12
|
PROTOCOL_VERSION = 2
|
5
13
|
end
|
6
14
|
end
|
7
15
|
end
|
8
16
|
|
9
|
-
require "hrr_rb_sftp/protocol/version2/
|
10
|
-
require "hrr_rb_sftp/protocol/version2/
|
17
|
+
require "hrr_rb_sftp/protocol/version2/data_types"
|
18
|
+
require "hrr_rb_sftp/protocol/version2/packets"
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module HrrRbSftp
|
2
|
+
class Protocol
|
3
|
+
module Version2
|
4
|
+
|
5
|
+
#
|
6
|
+
# This class implements SFTP protocol version 2 packet types, formats, and responders.
|
7
|
+
#
|
8
|
+
class Packets < Version1::Packets
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
require "hrr_rb_sftp/protocol/version2/packets/018_ssh_fxp_rename"
|
@@ -0,0 +1,91 @@
|
|
1
|
+
module HrrRbSftp
|
2
|
+
class Protocol
|
3
|
+
module Version2
|
4
|
+
class Packets
|
5
|
+
|
6
|
+
#
|
7
|
+
# This class implements SFTP protocol version 2 SSH_FXP_RENAME packet type, format, and responder.
|
8
|
+
#
|
9
|
+
class SSH_FXP_RENAME < Packets::Packet
|
10
|
+
|
11
|
+
#
|
12
|
+
# Represents SSH_FXP_RENAME packet type.
|
13
|
+
#
|
14
|
+
TYPE = 18
|
15
|
+
|
16
|
+
#
|
17
|
+
# Represents SSH_FXP_RENAME packet format.
|
18
|
+
#
|
19
|
+
FORMAT = [
|
20
|
+
[DataTypes::Byte, :"type" ],
|
21
|
+
[DataTypes::Uint32, :"request-id"],
|
22
|
+
[DataTypes::String, :"oldpath" ],
|
23
|
+
[DataTypes::String, :"newpath" ],
|
24
|
+
]
|
25
|
+
|
26
|
+
#
|
27
|
+
# Responds to SSH_FXP_RENAME request.
|
28
|
+
#
|
29
|
+
# @param request [Hash{Symbol=>Object}] SSH_FXP_RENAME request represented in Hash.
|
30
|
+
# @return [Hash{Symbol=>Object}] Response represented in Hash. Its type is SSH_FXP_STATUS.
|
31
|
+
#
|
32
|
+
def respond_to request
|
33
|
+
begin
|
34
|
+
oldpath = request[:"oldpath"]
|
35
|
+
newpath = request[:"newpath"]
|
36
|
+
log_debug { "File.exist?(#{newpath.inspect})" }
|
37
|
+
if File.exist?(newpath)
|
38
|
+
log_debug { "File exists" }
|
39
|
+
{
|
40
|
+
:"type" => Packets::SSH_FXP_STATUS::TYPE,
|
41
|
+
:"request-id" => request[:"request-id"],
|
42
|
+
:"code" => Packets::SSH_FXP_STATUS::SSH_FX_FAILURE,
|
43
|
+
:"error message" => "File exists",
|
44
|
+
:"language tag" => "",
|
45
|
+
}
|
46
|
+
else
|
47
|
+
log_debug { "File does not exist" }
|
48
|
+
log_debug { "File.rename(#{oldpath.inspect}, #{newpath.inspect})" }
|
49
|
+
File.rename(oldpath, newpath)
|
50
|
+
{
|
51
|
+
:"type" => Packets::SSH_FXP_STATUS::TYPE,
|
52
|
+
:"request-id" => request[:"request-id"],
|
53
|
+
:"code" => Packets::SSH_FXP_STATUS::SSH_FX_OK,
|
54
|
+
:"error message" => "Success",
|
55
|
+
:"language tag" => "",
|
56
|
+
}
|
57
|
+
end
|
58
|
+
rescue Errno::ENOENT => e
|
59
|
+
log_debug { e.message }
|
60
|
+
{
|
61
|
+
:"type" => Packets::SSH_FXP_STATUS::TYPE,
|
62
|
+
:"request-id" => request[:"request-id"],
|
63
|
+
:"code" => Packets::SSH_FXP_STATUS::SSH_FX_NO_SUCH_FILE,
|
64
|
+
:"error message" => "No such file or directory",
|
65
|
+
:"language tag" => "",
|
66
|
+
}
|
67
|
+
rescue Errno::EACCES => e
|
68
|
+
log_debug { e.message }
|
69
|
+
{
|
70
|
+
:"type" => Packets::SSH_FXP_STATUS::TYPE,
|
71
|
+
:"request-id" => request[:"request-id"],
|
72
|
+
:"code" => Packets::SSH_FXP_STATUS::SSH_FX_PERMISSION_DENIED,
|
73
|
+
:"error message" => "Permission denied",
|
74
|
+
:"language tag" => "",
|
75
|
+
}
|
76
|
+
rescue => e
|
77
|
+
log_error { [e.backtrace[0], ": ", e.message, " (", e.class.to_s, ")\n\t", e.backtrace[1..-1].join("\n\t")].join }
|
78
|
+
{
|
79
|
+
:"type" => Packets::SSH_FXP_STATUS::TYPE,
|
80
|
+
:"request-id" => request[:"request-id"],
|
81
|
+
:"code" => Packets::SSH_FXP_STATUS::SSH_FX_FAILURE,
|
82
|
+
:"error message" => e.message,
|
83
|
+
:"language tag" => "",
|
84
|
+
}
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
@@ -1,10 +1,19 @@
|
|
1
1
|
module HrrRbSftp
|
2
2
|
class Protocol
|
3
|
-
|
3
|
+
|
4
|
+
#
|
5
|
+
# This module implements SFTP protocol version 3 packet types, formats, and responders.
|
6
|
+
#
|
7
|
+
module Version3
|
8
|
+
|
9
|
+
#
|
10
|
+
# Represents SFTP protocol version 3.
|
11
|
+
#
|
4
12
|
PROTOCOL_VERSION = 3
|
5
13
|
end
|
6
14
|
end
|
7
15
|
end
|
8
16
|
|
9
|
-
require "hrr_rb_sftp/protocol/version3/
|
10
|
-
require "hrr_rb_sftp/protocol/version3/
|
17
|
+
require "hrr_rb_sftp/protocol/version3/data_types"
|
18
|
+
require "hrr_rb_sftp/protocol/version3/extensions"
|
19
|
+
require "hrr_rb_sftp/protocol/version3/packets"
|
@@ -0,0 +1,94 @@
|
|
1
|
+
module HrrRbSftp
|
2
|
+
class Protocol
|
3
|
+
module Version3
|
4
|
+
|
5
|
+
#
|
6
|
+
# This class implements SFTP protocol version 3 extension formats and responders.
|
7
|
+
#
|
8
|
+
class Extensions
|
9
|
+
include Loggable
|
10
|
+
|
11
|
+
#
|
12
|
+
# @return [Array<Class>] A list of classes that has EXTENSION_NAME constant.
|
13
|
+
#
|
14
|
+
def self.extension_classes
|
15
|
+
constants.map{|c| const_get(c)}.select{|c| c.respond_to?(:const_defined?) && c.const_defined?(:EXTENSION_NAME)}
|
16
|
+
end
|
17
|
+
|
18
|
+
#
|
19
|
+
# @return [Array] A list of extension-pair that the library supports.
|
20
|
+
#
|
21
|
+
def self.extension_pairs
|
22
|
+
extension_classes.map{|c| {:"extension-name" => c::EXTENSION_NAME, :"extension-data" => c::EXTENSION_DATA}}
|
23
|
+
end
|
24
|
+
|
25
|
+
#
|
26
|
+
# @param context [Hash] Contextual variables.
|
27
|
+
# - :version (Integer) - Negotiated protocol version.
|
28
|
+
# - :handles (Hash\\{String=>File, Dir\}) - Opened handles.
|
29
|
+
# @param logger [Logger] Logger.
|
30
|
+
#
|
31
|
+
def initialize context, logger: nil
|
32
|
+
self.logger = logger
|
33
|
+
|
34
|
+
@conditional_request_format = conditional_request_format
|
35
|
+
@conditional_reply_format = conditional_reply_format
|
36
|
+
@extensions = extension_classes.map{ |c|
|
37
|
+
extension = c.new(context, logger: logger)
|
38
|
+
(c::REQUEST_FORMAT[:"extended-request"] || {}).keys.map{|key| {key => extension} }.inject({}, :merge)
|
39
|
+
}.inject({}, :merge)
|
40
|
+
end
|
41
|
+
|
42
|
+
#
|
43
|
+
# @return [Boolean] true if request's extended-request is supported. false if not.
|
44
|
+
#
|
45
|
+
def respond_to? request
|
46
|
+
extended_request = request[:"extended-request"]
|
47
|
+
@extensions.has_key?(extended_request)
|
48
|
+
end
|
49
|
+
|
50
|
+
#
|
51
|
+
# @return [Hash{Symbol=>Object] Response represented in Hash.
|
52
|
+
#
|
53
|
+
def respond_to request
|
54
|
+
extended_request = request[:"extended-request"]
|
55
|
+
@extensions[extended_request].respond_to request
|
56
|
+
end
|
57
|
+
|
58
|
+
#
|
59
|
+
# @return [Hash{Symbol=>Hash{String=>Array<Array(Object, Symbol)>}}] Conditional format used in extended-request packet.
|
60
|
+
#
|
61
|
+
def conditional_request_format
|
62
|
+
@conditional_request_format ||= request_formats.inject({}){|h1,h2| h1.merge(h2){|k,v1,v2| v1.merge(v2)}}
|
63
|
+
end
|
64
|
+
|
65
|
+
#
|
66
|
+
# @return [Hash{Symbol=>Hash{String=>Array<Array(Object, Symbol)>}}] Conditional format used in extended-reply packet.
|
67
|
+
#
|
68
|
+
def conditional_reply_format
|
69
|
+
@conditional_reply_format ||= reply_formats.inject({}){|h1,h2| h1.merge(h2){|k,v1,v2| v1.merge(v2)}}
|
70
|
+
end
|
71
|
+
|
72
|
+
private
|
73
|
+
|
74
|
+
def extension_classes
|
75
|
+
self.class.constants.map{|c| self.class.const_get(c)}.select{|c| c.respond_to?(:const_defined?) && c.const_defined?(:EXTENSION_NAME)}
|
76
|
+
end
|
77
|
+
|
78
|
+
def request_formats
|
79
|
+
extension_classes.map{|c| c.const_defined?(:REQUEST_FORMAT) ? c::REQUEST_FORMAT : {}}
|
80
|
+
end
|
81
|
+
|
82
|
+
def reply_formats
|
83
|
+
extension_classes.map{|c| c.const_defined?(:REPLY_FORMAT) ? c::REPLY_FORMAT : {}}
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
require "hrr_rb_sftp/protocol/version3/extensions/extension"
|
91
|
+
require "hrr_rb_sftp/protocol/version3/extensions/hardlink_at_openssh_com"
|
92
|
+
require "hrr_rb_sftp/protocol/version3/extensions/fsync_at_openssh_com"
|
93
|
+
require "hrr_rb_sftp/protocol/version3/extensions/posix_rename_at_openssh_com"
|
94
|
+
require "hrr_rb_sftp/protocol/version3/extensions/lsetstat_at_openssh_com"
|
@@ -0,0 +1,58 @@
|
|
1
|
+
module HrrRbSftp
|
2
|
+
class Protocol
|
3
|
+
module Version3
|
4
|
+
class Extensions
|
5
|
+
|
6
|
+
#
|
7
|
+
# This class implements base extension operations and is to be inherited by each extension class.
|
8
|
+
#
|
9
|
+
class Extension
|
10
|
+
include Loggable
|
11
|
+
|
12
|
+
#
|
13
|
+
# Returns a new instance of a class that includes this module.
|
14
|
+
#
|
15
|
+
# @param context [Hash] Contextual variables.
|
16
|
+
# - :version (Integer) - Negotiated protocol version.
|
17
|
+
# - :handles (Hash\\{String=>File, Dir\}) - Opened handles.
|
18
|
+
# @param logger [Logger] Logger.
|
19
|
+
#
|
20
|
+
def initialize context, logger: nil
|
21
|
+
self.logger = logger
|
22
|
+
|
23
|
+
@context = context
|
24
|
+
end
|
25
|
+
|
26
|
+
#
|
27
|
+
# Returns contextual variables.
|
28
|
+
#
|
29
|
+
# @return [Hash] Contextual variables.
|
30
|
+
# - :version (Integer) - Negotiated protocol version.
|
31
|
+
# - :handles (Hash\\{String=>File, Dir\}) - Opened handles.
|
32
|
+
#
|
33
|
+
def context
|
34
|
+
@context
|
35
|
+
end
|
36
|
+
|
37
|
+
#
|
38
|
+
# Returns Negotiated protocol version.
|
39
|
+
#
|
40
|
+
# @return [Integer] Negotiated protocol version.
|
41
|
+
#
|
42
|
+
def version
|
43
|
+
@context[:version]
|
44
|
+
end
|
45
|
+
|
46
|
+
#
|
47
|
+
# Returns opened handles.
|
48
|
+
#
|
49
|
+
# @return [Hash{String=>File, Dir}] Opened handles.
|
50
|
+
#
|
51
|
+
def handles
|
52
|
+
@context[:handles]
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
module HrrRbSftp
|
2
|
+
class Protocol
|
3
|
+
module Version3
|
4
|
+
class Extensions
|
5
|
+
|
6
|
+
#
|
7
|
+
# This class implements fsync@openssh.com version 1 extension format and responder.
|
8
|
+
#
|
9
|
+
class FsyncAtOpensshCom < Extension
|
10
|
+
|
11
|
+
#
|
12
|
+
# Represents fsync@openssh.com version 1 extension name.
|
13
|
+
#
|
14
|
+
EXTENSION_NAME = "fsync@openssh.com"
|
15
|
+
|
16
|
+
#
|
17
|
+
# Represents fsync@openssh.com version 1 extension data.
|
18
|
+
#
|
19
|
+
EXTENSION_DATA = "1"
|
20
|
+
|
21
|
+
#
|
22
|
+
# Represents SSH_FXP_EXTENDED packet additional format for fsync@openssh.com version 1 extension.
|
23
|
+
#
|
24
|
+
REQUEST_FORMAT = {
|
25
|
+
:"extended-request" => {
|
26
|
+
"fsync@openssh.com" => [
|
27
|
+
[DataTypes::String, :"handle"],
|
28
|
+
],
|
29
|
+
},
|
30
|
+
}
|
31
|
+
|
32
|
+
#
|
33
|
+
# Responds to SSH_FXP_EXTENDED request with fsync@openssh.com extended-request.
|
34
|
+
#
|
35
|
+
# @param request [Hash{Symbol=>Object}] SSH_FXP_EXTENDED request represented in Hash.
|
36
|
+
# @return [Hash{Symbol=>Object}] Response represented in Hash. Its type is SSH_FXP_STATUS.
|
37
|
+
#
|
38
|
+
def respond_to request
|
39
|
+
begin
|
40
|
+
raise "Specified handle does not exist" unless handles.has_key?(request[:"handle"])
|
41
|
+
log_debug { "file = handles[#{request[:"handle"].inspect}]" }
|
42
|
+
file = handles[request[:"handle"]]
|
43
|
+
log_debug { "file.fsync" }
|
44
|
+
file.fsync
|
45
|
+
{
|
46
|
+
:"type" => Packets::SSH_FXP_STATUS::TYPE,
|
47
|
+
:"request-id" => request[:"request-id"],
|
48
|
+
:"code" => Packets::SSH_FXP_STATUS::SSH_FX_OK,
|
49
|
+
:"error message" => "Success",
|
50
|
+
:"language tag" => "",
|
51
|
+
}
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|