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
@@ -1,22 +1,39 @@
|
|
1
1
|
module HrrRbSftp
|
2
2
|
class Protocol
|
3
|
-
|
4
|
-
|
5
|
-
class SSH_FXP_FSTAT
|
6
|
-
include Common::Packetable
|
3
|
+
module Version1
|
4
|
+
class Packets
|
7
5
|
|
6
|
+
#
|
7
|
+
# This class implements SFTP protocol version 1 SSH_FXP_FSTAT packet type, format, and responder.
|
8
|
+
#
|
9
|
+
class SSH_FXP_FSTAT < Packet
|
10
|
+
|
11
|
+
#
|
12
|
+
# Represents SSH_FXP_FSTAT packet type.
|
13
|
+
#
|
8
14
|
TYPE = 8
|
9
15
|
|
16
|
+
#
|
17
|
+
# Represents SSH_FXP_FSTAT packet format.
|
18
|
+
#
|
10
19
|
FORMAT = [
|
11
|
-
[
|
12
|
-
[
|
13
|
-
[
|
20
|
+
[DataTypes::Byte, :"type" ],
|
21
|
+
[DataTypes::Uint32, :"request-id"],
|
22
|
+
[DataTypes::String, :"handle" ],
|
14
23
|
]
|
15
24
|
|
25
|
+
#
|
26
|
+
# Responds to SSH_FXP_FSTAT request.
|
27
|
+
#
|
28
|
+
# @param request [Hash{Symbol=>Object}] SSH_FXP_FSTAT request represented in Hash.
|
29
|
+
# @return [Hash{Symbol=>Object}] Response represented in Hash. In case of success, its type is SSH_FXP_ATTRS. In other cases, its type is SSH_FXP_STATUS.
|
30
|
+
#
|
16
31
|
def respond_to request
|
17
32
|
begin
|
18
|
-
raise "Specified handle does not exist" unless
|
19
|
-
file =
|
33
|
+
raise "Specified handle does not exist" unless handles.has_key?(request[:"handle"])
|
34
|
+
log_debug { "file = handles[#{request[:"handle"].inspect}]" }
|
35
|
+
file = handles[request[:"handle"]]
|
36
|
+
log_debug { "file.stat" }
|
20
37
|
stat = file.stat
|
21
38
|
attrs = Hash.new
|
22
39
|
attrs[:"size"] = stat.size if stat.size
|
@@ -0,0 +1,92 @@
|
|
1
|
+
module HrrRbSftp
|
2
|
+
class Protocol
|
3
|
+
module Version1
|
4
|
+
class Packets
|
5
|
+
|
6
|
+
#
|
7
|
+
# This class implements SFTP protocol version 1 SSH_FXP_SETSTAT packet type, format, and responder.
|
8
|
+
#
|
9
|
+
class SSH_FXP_SETSTAT < Packet
|
10
|
+
|
11
|
+
#
|
12
|
+
# Represents SSH_FXP_SETSTAT packet type.
|
13
|
+
#
|
14
|
+
TYPE = 9
|
15
|
+
|
16
|
+
#
|
17
|
+
# Represents SSH_FXP_SETSTAT packet format.
|
18
|
+
#
|
19
|
+
FORMAT = [
|
20
|
+
[DataTypes::Byte, :"type" ],
|
21
|
+
[DataTypes::Uint32, :"request-id"],
|
22
|
+
[DataTypes::String, :"path" ],
|
23
|
+
[DataTypes::Attrs, :"attrs" ],
|
24
|
+
]
|
25
|
+
|
26
|
+
#
|
27
|
+
# Responds to SSH_FXP_SETSTAT request.
|
28
|
+
#
|
29
|
+
# @param request [Hash{Symbol=>Object}] SSH_FXP_SETSTAT 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
|
+
path = request[:"path"]
|
35
|
+
attrs = request[:"attrs"]
|
36
|
+
if attrs.has_key?(:"size")
|
37
|
+
log_debug { "File.truncate(#{path.inspect}, #{attrs[:"size"].inspect})" }
|
38
|
+
File.truncate(path, attrs[:"size"])
|
39
|
+
end
|
40
|
+
if attrs.has_key?(:"permissions")
|
41
|
+
log_debug { "File.chmod(#{attrs[:"permissions"].inspect}, #{path.inspect})" }
|
42
|
+
File.chmod(attrs[:"permissions"], path)
|
43
|
+
end
|
44
|
+
if attrs.has_key?(:"atime") && attrs.has_key?(:"mtime")
|
45
|
+
log_debug { "File.utime(#{attrs[:"atime"].inspect}, #{attrs[:"mtime"].inspect}, #{path.inspect})" }
|
46
|
+
File.utime(attrs[:"atime"], attrs[:"mtime"], path)
|
47
|
+
end
|
48
|
+
if attrs.has_key?(:"uid") && attrs.has_key?(:"gid")
|
49
|
+
log_debug { "File.chown(#{attrs[:"uid"].inspect}, #{attrs[:"gid"].inspect}, #{path.inspect})" }
|
50
|
+
File.chown(attrs[:"uid"], attrs[:"gid"], path)
|
51
|
+
end
|
52
|
+
{
|
53
|
+
:"type" => SSH_FXP_STATUS::TYPE,
|
54
|
+
:"request-id" => request[:"request-id"],
|
55
|
+
:"code" => SSH_FXP_STATUS::SSH_FX_OK,
|
56
|
+
:"error message" => "Success",
|
57
|
+
:"language tag" => "",
|
58
|
+
}
|
59
|
+
rescue Errno::ENOENT => e
|
60
|
+
log_debug { e.message }
|
61
|
+
{
|
62
|
+
:"type" => SSH_FXP_STATUS::TYPE,
|
63
|
+
:"request-id" => request[:"request-id"],
|
64
|
+
:"code" => SSH_FXP_STATUS::SSH_FX_NO_SUCH_FILE,
|
65
|
+
:"error message" => "No such file or directory",
|
66
|
+
:"language tag" => "",
|
67
|
+
}
|
68
|
+
rescue Errno::EACCES, Errno::EPERM => e
|
69
|
+
log_debug { e.message }
|
70
|
+
{
|
71
|
+
:"type" => SSH_FXP_STATUS::TYPE,
|
72
|
+
:"request-id" => request[:"request-id"],
|
73
|
+
:"code" => SSH_FXP_STATUS::SSH_FX_PERMISSION_DENIED,
|
74
|
+
:"error message" => "Permission denied",
|
75
|
+
:"language tag" => "",
|
76
|
+
}
|
77
|
+
rescue => e
|
78
|
+
log_error { [e.backtrace[0], ": ", e.message, " (", e.class.to_s, ")\n\t", e.backtrace[1..-1].join("\n\t")].join }
|
79
|
+
{
|
80
|
+
:"type" => SSH_FXP_STATUS::TYPE,
|
81
|
+
:"request-id" => request[:"request-id"],
|
82
|
+
:"code" => SSH_FXP_STATUS::SSH_FX_FAILURE,
|
83
|
+
:"error message" => e.message,
|
84
|
+
:"language tag" => "",
|
85
|
+
}
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
@@ -0,0 +1,85 @@
|
|
1
|
+
module HrrRbSftp
|
2
|
+
class Protocol
|
3
|
+
module Version1
|
4
|
+
class Packets
|
5
|
+
|
6
|
+
#
|
7
|
+
# This class implements SFTP protocol version 1 SSH_FXP_FSETSTAT packet type, format, and responder.
|
8
|
+
#
|
9
|
+
class SSH_FXP_FSETSTAT < Packet
|
10
|
+
|
11
|
+
#
|
12
|
+
# Represents SSH_FXP_FSETSTAT packet type.
|
13
|
+
#
|
14
|
+
TYPE = 10
|
15
|
+
|
16
|
+
#
|
17
|
+
# Represents SSH_FXP_FSETSTAT packet format.
|
18
|
+
#
|
19
|
+
FORMAT = [
|
20
|
+
[DataTypes::Byte, :"type" ],
|
21
|
+
[DataTypes::Uint32, :"request-id"],
|
22
|
+
[DataTypes::String, :"handle" ],
|
23
|
+
[DataTypes::Attrs, :"attrs" ],
|
24
|
+
]
|
25
|
+
|
26
|
+
#
|
27
|
+
# Responds to SSH_FXP_FSETSTAT request.
|
28
|
+
#
|
29
|
+
# @param request [Hash{Symbol=>Object}] SSH_FXP_FSETSTAT 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
|
+
raise "Specified handle does not exist" unless handles.has_key?(request[:"handle"])
|
35
|
+
log_debug { "file = handles[#{request[:"handle"].inspect}]" }
|
36
|
+
file = handles[request[:"handle"]]
|
37
|
+
attrs = request[:"attrs"]
|
38
|
+
if attrs.has_key?(:"size")
|
39
|
+
log_debug { "file.truncate(#{attrs[:"size"].inspect})" }
|
40
|
+
file.truncate(attrs[:"size"])
|
41
|
+
end
|
42
|
+
if attrs.has_key?(:"permissions")
|
43
|
+
log_debug { "file.chmod(#{attrs[:"permissions"].inspect})" }
|
44
|
+
file.chmod(attrs[:"permissions"])
|
45
|
+
end
|
46
|
+
if attrs.has_key?(:"atime") && attrs.has_key?(:"mtime")
|
47
|
+
log_debug { "File.utime(#{attrs[:"atime"].inspect}, #{attrs[:"mtime"].inspect}, #{file.path.inspect})" }
|
48
|
+
File.utime(attrs[:"atime"], attrs[:"mtime"], file.path)
|
49
|
+
end
|
50
|
+
if attrs.has_key?(:"uid") && attrs.has_key?(:"gid")
|
51
|
+
log_debug { "file.chown(#{attrs[:"uid"].inspect}, #{attrs[:"gid"].inspect})" }
|
52
|
+
file.chown(attrs[:"uid"], attrs[:"gid"])
|
53
|
+
end
|
54
|
+
{
|
55
|
+
:"type" => SSH_FXP_STATUS::TYPE,
|
56
|
+
:"request-id" => request[:"request-id"],
|
57
|
+
:"code" => SSH_FXP_STATUS::SSH_FX_OK,
|
58
|
+
:"error message" => "Success",
|
59
|
+
:"language tag" => "",
|
60
|
+
}
|
61
|
+
rescue Errno::EPERM => e
|
62
|
+
log_debug { e.message }
|
63
|
+
{
|
64
|
+
:"type" => SSH_FXP_STATUS::TYPE,
|
65
|
+
:"request-id" => request[:"request-id"],
|
66
|
+
:"code" => SSH_FXP_STATUS::SSH_FX_PERMISSION_DENIED,
|
67
|
+
:"error message" => "Permission denied",
|
68
|
+
:"language tag" => "",
|
69
|
+
}
|
70
|
+
rescue => e
|
71
|
+
log_error { [e.backtrace[0], ": ", e.message, " (", e.class.to_s, ")\n\t", e.backtrace[1..-1].join("\n\t")].join }
|
72
|
+
{
|
73
|
+
:"type" => SSH_FXP_STATUS::TYPE,
|
74
|
+
:"request-id" => request[:"request-id"],
|
75
|
+
:"code" => SSH_FXP_STATUS::SSH_FX_FAILURE,
|
76
|
+
:"error message" => e.message,
|
77
|
+
:"language tag" => "",
|
78
|
+
}
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
@@ -1,29 +1,48 @@
|
|
1
1
|
module HrrRbSftp
|
2
2
|
class Protocol
|
3
|
-
|
4
|
-
|
5
|
-
class SSH_FXP_OPENDIR
|
6
|
-
include Common::Packetable
|
3
|
+
module Version1
|
4
|
+
class Packets
|
7
5
|
|
6
|
+
#
|
7
|
+
# This class implements SFTP protocol version 1 SSH_FXP_OPENDIR packet type, format, and responder.
|
8
|
+
#
|
9
|
+
class SSH_FXP_OPENDIR < Packet
|
10
|
+
|
11
|
+
#
|
12
|
+
# Represents SSH_FXP_OPENDIR packet type.
|
13
|
+
#
|
8
14
|
TYPE = 11
|
9
15
|
|
16
|
+
#
|
17
|
+
# Represents SSH_FXP_OPENDIR packet format.
|
18
|
+
#
|
10
19
|
FORMAT = [
|
11
|
-
[
|
12
|
-
[
|
13
|
-
[
|
20
|
+
[DataTypes::Byte, :"type" ],
|
21
|
+
[DataTypes::Uint32, :"request-id"],
|
22
|
+
[DataTypes::String, :"path" ],
|
14
23
|
]
|
15
24
|
|
25
|
+
#
|
26
|
+
# Responds to SSH_FXP_OPENDIR request.
|
27
|
+
#
|
28
|
+
# @param request [Hash{Symbol=>Object}] SSH_FXP_OPENDIR request represented in Hash.
|
29
|
+
# @return [Hash{Symbol=>Object}] Response represented in Hash. In case of success, its type is SSH_FXP_HANDLE. In other cases, its type is SSH_FXP_STATUS.
|
30
|
+
#
|
16
31
|
def respond_to request
|
17
32
|
begin
|
33
|
+
log_debug { "dir = Dir.open(#{request[:"path"].inspect})" }
|
18
34
|
dir = ::Dir.open(request[:"path"])
|
35
|
+
log_debug { "handle = #{dir.object_id.to_s(16).inspect}" }
|
19
36
|
handle = dir.object_id.to_s(16)
|
20
|
-
|
37
|
+
log_debug { "handles[#{handle.inspect}] = dir" }
|
38
|
+
handles[handle] = dir
|
21
39
|
{
|
22
40
|
:"type" => SSH_FXP_HANDLE::TYPE,
|
23
41
|
:"request-id" => request[:"request-id"],
|
24
42
|
:"handle" => handle,
|
25
43
|
}
|
26
|
-
rescue Errno::ENOENT
|
44
|
+
rescue Errno::ENOENT => e
|
45
|
+
log_debug { e.message }
|
27
46
|
{
|
28
47
|
:"type" => SSH_FXP_STATUS::TYPE,
|
29
48
|
:"request-id" => request[:"request-id"],
|
@@ -31,7 +50,8 @@ module HrrRbSftp
|
|
31
50
|
:"error message" => "No such file or directory",
|
32
51
|
:"language tag" => "",
|
33
52
|
}
|
34
|
-
rescue Errno::EACCES
|
53
|
+
rescue Errno::EACCES => e
|
54
|
+
log_debug { e.message }
|
35
55
|
{
|
36
56
|
:"type" => SSH_FXP_STATUS::TYPE,
|
37
57
|
:"request-id" => request[:"request-id"],
|
@@ -39,7 +59,8 @@ module HrrRbSftp
|
|
39
59
|
:"error message" => "Permission denied",
|
40
60
|
:"language tag" => "",
|
41
61
|
}
|
42
|
-
rescue Errno::ENOTDIR
|
62
|
+
rescue Errno::ENOTDIR => e
|
63
|
+
log_debug { e.message }
|
43
64
|
{
|
44
65
|
:"type" => SSH_FXP_STATUS::TYPE,
|
45
66
|
:"request-id" => request[:"request-id"],
|
@@ -1,18 +1,84 @@
|
|
1
1
|
module HrrRbSftp
|
2
2
|
class Protocol
|
3
|
-
|
4
|
-
|
5
|
-
class SSH_FXP_READDIR
|
6
|
-
include Common::Packetable
|
3
|
+
module Version1
|
4
|
+
class Packets
|
7
5
|
|
6
|
+
#
|
7
|
+
# This class implements SFTP protocol version 1 SSH_FXP_READDIR packet type, format, and responder.
|
8
|
+
#
|
9
|
+
class SSH_FXP_READDIR < Packet
|
10
|
+
|
11
|
+
#
|
12
|
+
# Represents SSH_FXP_READDIR packet type.
|
13
|
+
#
|
8
14
|
TYPE = 12
|
9
15
|
|
16
|
+
#
|
17
|
+
# Represents SSH_FXP_READDIR packet format.
|
18
|
+
#
|
10
19
|
FORMAT = [
|
11
|
-
[
|
12
|
-
[
|
13
|
-
[
|
20
|
+
[DataTypes::Byte, :"type" ],
|
21
|
+
[DataTypes::Uint32, :"request-id"],
|
22
|
+
[DataTypes::String, :"handle" ],
|
14
23
|
]
|
15
24
|
|
25
|
+
#
|
26
|
+
# Responds to SSH_FXP_READDIR request.
|
27
|
+
#
|
28
|
+
# @param request [Hash{Symbol=>Object}] SSH_FXP_READDIR request represented in Hash.
|
29
|
+
# @return [Hash{Symbol=>Object}] Response represented in Hash. In case of success, its type is SSH_FXP_NAME. In other cases, its type is SSH_FXP_STATUS.
|
30
|
+
#
|
31
|
+
def respond_to request
|
32
|
+
begin
|
33
|
+
raise "Specified handle does not exist" unless handles.has_key?(request[:"handle"])
|
34
|
+
log_debug { "dir = handles[#{request[:"handle"].inspect}]" }
|
35
|
+
dir = handles[request[:"handle"]]
|
36
|
+
raise "Specified handle is not directory" unless dir.instance_of?(::Dir)
|
37
|
+
entries = ::Array.new
|
38
|
+
while entry = dir.read
|
39
|
+
log_debug { "#{entry.inspect} = dir.read" }
|
40
|
+
log_debug { "entries.push #{entry.inspect}" }
|
41
|
+
entries.push entry
|
42
|
+
end
|
43
|
+
unless entries.empty?
|
44
|
+
log_debug { "entries is not empty" }
|
45
|
+
log_debug { "count = #{entries.size.inspect}" }
|
46
|
+
count = entries.size
|
47
|
+
response = {
|
48
|
+
:"type" => SSH_FXP_NAME::TYPE,
|
49
|
+
:"request-id" => request[:"request-id"],
|
50
|
+
:"count" => count,
|
51
|
+
}
|
52
|
+
entries.each.with_index do |entry, idx|
|
53
|
+
response[:"filename[#{idx}]"] = entry
|
54
|
+
response[:"longname[#{idx}]"] = longname(dir, entry)
|
55
|
+
response[:"attrs[#{idx}]"] = attrs(dir, entry)
|
56
|
+
end
|
57
|
+
response
|
58
|
+
else
|
59
|
+
log_debug { "entries is empty" }
|
60
|
+
{
|
61
|
+
:"type" => SSH_FXP_STATUS::TYPE,
|
62
|
+
:"request-id" => request[:"request-id"],
|
63
|
+
:"code" => SSH_FXP_STATUS::SSH_FX_EOF,
|
64
|
+
:"error message" => "End of file",
|
65
|
+
:"language tag" => "",
|
66
|
+
}
|
67
|
+
end
|
68
|
+
rescue => e
|
69
|
+
log_error { [e.backtrace[0], ": ", e.message, " (", e.class.to_s, ")\n\t", e.backtrace[1..-1].join("\n\t")].join }
|
70
|
+
{
|
71
|
+
:"type" => SSH_FXP_STATUS::TYPE,
|
72
|
+
:"request-id" => request[:"request-id"],
|
73
|
+
:"code" => SSH_FXP_STATUS::SSH_FX_FAILURE,
|
74
|
+
:"error message" => e.message,
|
75
|
+
:"language tag" => "",
|
76
|
+
}
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
private
|
81
|
+
|
16
82
|
def longname_permissions stat
|
17
83
|
s = ::String.new
|
18
84
|
s += case stat.mode & 0170000
|
@@ -85,48 +151,6 @@ module HrrRbSftp
|
|
85
151
|
attrs[:"mtime"] = stat.mtime.to_i if stat.mtime
|
86
152
|
attrs
|
87
153
|
end
|
88
|
-
|
89
|
-
def respond_to request
|
90
|
-
begin
|
91
|
-
raise "Specified handle does not exist" unless @handles.has_key?(request[:"handle"])
|
92
|
-
dir = @handles[request[:"handle"]]
|
93
|
-
raise "Specified handle is not directory" unless dir.instance_of?(::Dir)
|
94
|
-
entries = ::Array.new
|
95
|
-
while entry = dir.read
|
96
|
-
entries.push entry
|
97
|
-
end
|
98
|
-
unless entries.empty?
|
99
|
-
response = {
|
100
|
-
:"type" => SSH_FXP_NAME::TYPE,
|
101
|
-
:"request-id" => request[:"request-id"],
|
102
|
-
:"count" => entries.size,
|
103
|
-
}
|
104
|
-
entries.each.with_index do |entry, idx|
|
105
|
-
response[:"filename[#{idx}]"] = entry
|
106
|
-
response[:"longname[#{idx}]"] = longname(dir, entry)
|
107
|
-
response[:"attrs[#{idx}]"] = attrs(dir, entry)
|
108
|
-
end
|
109
|
-
response
|
110
|
-
else
|
111
|
-
{
|
112
|
-
:"type" => SSH_FXP_STATUS::TYPE,
|
113
|
-
:"request-id" => request[:"request-id"],
|
114
|
-
:"code" => SSH_FXP_STATUS::SSH_FX_EOF,
|
115
|
-
:"error message" => "End of file",
|
116
|
-
:"language tag" => "",
|
117
|
-
}
|
118
|
-
end
|
119
|
-
rescue => e
|
120
|
-
log_error { [e.backtrace[0], ": ", e.message, " (", e.class.to_s, ")\n\t", e.backtrace[1..-1].join("\n\t")].join }
|
121
|
-
{
|
122
|
-
:"type" => SSH_FXP_STATUS::TYPE,
|
123
|
-
:"request-id" => request[:"request-id"],
|
124
|
-
:"code" => SSH_FXP_STATUS::SSH_FX_FAILURE,
|
125
|
-
:"error message" => e.message,
|
126
|
-
:"language tag" => "",
|
127
|
-
}
|
128
|
-
end
|
129
|
-
end
|
130
154
|
end
|
131
155
|
end
|
132
156
|
end
|
@@ -1,20 +1,36 @@
|
|
1
1
|
module HrrRbSftp
|
2
2
|
class Protocol
|
3
|
-
|
4
|
-
|
5
|
-
class SSH_FXP_REMOVE
|
6
|
-
include Common::Packetable
|
3
|
+
module Version1
|
4
|
+
class Packets
|
7
5
|
|
6
|
+
#
|
7
|
+
# This class implements SFTP protocol version 1 SSH_FXP_REMOVE packet type, format, and responder.
|
8
|
+
#
|
9
|
+
class SSH_FXP_REMOVE < Packet
|
10
|
+
|
11
|
+
#
|
12
|
+
# Represents SSH_FXP_REMOVE packet type.
|
13
|
+
#
|
8
14
|
TYPE = 13
|
9
15
|
|
16
|
+
#
|
17
|
+
# Represents SSH_FXP_REMOVE packet format.
|
18
|
+
#
|
10
19
|
FORMAT = [
|
11
|
-
[
|
12
|
-
[
|
13
|
-
[
|
20
|
+
[DataTypes::Byte, :"type" ],
|
21
|
+
[DataTypes::Uint32, :"request-id"],
|
22
|
+
[DataTypes::String, :"filename" ],
|
14
23
|
]
|
15
24
|
|
25
|
+
#
|
26
|
+
# Responds to SSH_FXP_REMOVE request.
|
27
|
+
#
|
28
|
+
# @param request [Hash{Symbol=>Object}] SSH_FXP_REMOVE request represented in Hash.
|
29
|
+
# @return [Hash{Symbol=>Object}] Response represented in Hash. Its type is SSH_FXP_STATUS.
|
30
|
+
#
|
16
31
|
def respond_to request
|
17
32
|
begin
|
33
|
+
log_debug { "File.delete(#{request[:"filename"].inspect})" }
|
18
34
|
File.delete(request[:"filename"])
|
19
35
|
{
|
20
36
|
:"type" => SSH_FXP_STATUS::TYPE,
|
@@ -23,7 +39,8 @@ module HrrRbSftp
|
|
23
39
|
:"error message" => "Success",
|
24
40
|
:"language tag" => "",
|
25
41
|
}
|
26
|
-
rescue Errno::ENOENT
|
42
|
+
rescue Errno::ENOENT => e
|
43
|
+
log_debug { e.message }
|
27
44
|
{
|
28
45
|
:"type" => SSH_FXP_STATUS::TYPE,
|
29
46
|
:"request-id" => request[:"request-id"],
|
@@ -31,7 +48,8 @@ module HrrRbSftp
|
|
31
48
|
:"error message" => "No such file or directory",
|
32
49
|
:"language tag" => "",
|
33
50
|
}
|
34
|
-
rescue Errno::EACCES
|
51
|
+
rescue Errno::EACCES => e
|
52
|
+
log_debug { e.message }
|
35
53
|
{
|
36
54
|
:"type" => SSH_FXP_STATUS::TYPE,
|
37
55
|
:"request-id" => request[:"request-id"],
|