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.
Files changed (102) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +23 -0
  3. data/lib/hrr_rb_sftp.rb +79 -1
  4. data/lib/hrr_rb_sftp/loggable.rb +34 -0
  5. data/lib/hrr_rb_sftp/protocol.rb +39 -33
  6. data/lib/hrr_rb_sftp/protocol/common.rb +6 -3
  7. data/lib/hrr_rb_sftp/protocol/common/data_types.rb +19 -0
  8. data/lib/hrr_rb_sftp/protocol/common/data_types/byte.rb +40 -0
  9. data/lib/hrr_rb_sftp/protocol/common/data_types/extension_pair.rb +41 -0
  10. data/lib/hrr_rb_sftp/protocol/common/data_types/extension_pairs.rb +42 -0
  11. data/lib/hrr_rb_sftp/protocol/common/data_types/string.rb +42 -0
  12. data/lib/hrr_rb_sftp/protocol/common/data_types/uint32.rb +40 -0
  13. data/lib/hrr_rb_sftp/protocol/common/data_types/uint64.rb +40 -0
  14. data/lib/hrr_rb_sftp/protocol/common/packets.rb +16 -0
  15. data/lib/hrr_rb_sftp/protocol/common/packets/001_ssh_fxp_init.rb +27 -0
  16. data/lib/hrr_rb_sftp/protocol/common/packets/002_ssh_fxp_version.rb +28 -0
  17. data/lib/hrr_rb_sftp/protocol/common/packets/packet.rb +96 -0
  18. data/lib/hrr_rb_sftp/protocol/version1.rb +11 -3
  19. data/lib/hrr_rb_sftp/protocol/version1/data_types.rb +15 -0
  20. data/lib/hrr_rb_sftp/protocol/version1/data_types/attrs.rb +91 -0
  21. data/lib/hrr_rb_sftp/protocol/version1/packets.rb +72 -0
  22. data/lib/hrr_rb_sftp/protocol/version1/{packet → packets}/003_ssh_fxp_open.rb +94 -43
  23. data/lib/hrr_rb_sftp/protocol/version1/packets/004_ssh_fxp_close.rb +61 -0
  24. data/lib/hrr_rb_sftp/protocol/version1/packets/005_ssh_fxp_read.rb +72 -0
  25. data/lib/hrr_rb_sftp/protocol/version1/packets/006_ssh_fxp_write.rb +64 -0
  26. data/lib/hrr_rb_sftp/protocol/version1/{packet → packets}/007_ssh_fxp_lstat.rb +27 -9
  27. data/lib/hrr_rb_sftp/protocol/version1/{packet → packets}/008_ssh_fxp_fstat.rb +26 -9
  28. data/lib/hrr_rb_sftp/protocol/version1/packets/009_ssh_fxp_setstat.rb +92 -0
  29. data/lib/hrr_rb_sftp/protocol/version1/packets/010_ssh_fxp_fsetstat.rb +85 -0
  30. data/lib/hrr_rb_sftp/protocol/version1/{packet → packets}/011_ssh_fxp_opendir.rb +32 -11
  31. data/lib/hrr_rb_sftp/protocol/version1/{packet → packets}/012_ssh_fxp_readdir.rb +73 -49
  32. data/lib/hrr_rb_sftp/protocol/version1/{packet → packets}/013_ssh_fxp_remove.rb +27 -9
  33. data/lib/hrr_rb_sftp/protocol/version1/{packet → packets}/014_ssh_fxp_mkdir.rb +28 -10
  34. data/lib/hrr_rb_sftp/protocol/version1/{packet → packets}/015_ssh_fxp_rmdir.rb +32 -12
  35. data/lib/hrr_rb_sftp/protocol/version1/packets/016_ssh_fxp_realpath.rb +47 -0
  36. data/lib/hrr_rb_sftp/protocol/version1/{packet → packets}/017_ssh_fxp_stat.rb +27 -9
  37. data/lib/hrr_rb_sftp/protocol/version1/packets/101_ssh_fxp_status.rb +73 -0
  38. data/lib/hrr_rb_sftp/protocol/version1/packets/102_ssh_fxp_handle.rb +28 -0
  39. data/lib/hrr_rb_sftp/protocol/version1/packets/103_ssh_fxp_data.rb +28 -0
  40. data/lib/hrr_rb_sftp/protocol/version1/packets/104_ssh_fxp_name.rb +48 -0
  41. data/lib/hrr_rb_sftp/protocol/version1/packets/105_ssh_fxp_attrs.rb +28 -0
  42. data/lib/hrr_rb_sftp/protocol/version1/packets/packet.rb +57 -0
  43. data/lib/hrr_rb_sftp/protocol/version2.rb +11 -3
  44. data/lib/hrr_rb_sftp/protocol/version2/data_types.rb +13 -0
  45. data/lib/hrr_rb_sftp/protocol/version2/packets.rb +14 -0
  46. data/lib/hrr_rb_sftp/protocol/version2/packets/018_ssh_fxp_rename.rb +91 -0
  47. data/lib/hrr_rb_sftp/protocol/version3.rb +12 -3
  48. data/lib/hrr_rb_sftp/protocol/version3/data_types.rb +13 -0
  49. data/lib/hrr_rb_sftp/protocol/version3/extensions.rb +94 -0
  50. data/lib/hrr_rb_sftp/protocol/version3/extensions/extension.rb +58 -0
  51. data/lib/hrr_rb_sftp/protocol/version3/extensions/fsync_at_openssh_com.rb +59 -0
  52. data/lib/hrr_rb_sftp/protocol/version3/extensions/hardlink_at_openssh_com.rb +84 -0
  53. data/lib/hrr_rb_sftp/protocol/version3/extensions/lsetstat_at_openssh_com.rb +132 -0
  54. data/lib/hrr_rb_sftp/protocol/version3/extensions/posix_rename_at_openssh_com.rb +76 -0
  55. data/lib/hrr_rb_sftp/protocol/version3/packets.rb +19 -0
  56. data/lib/hrr_rb_sftp/protocol/version3/packets/014_ssh_fxp_mkdir.rb +75 -0
  57. data/lib/hrr_rb_sftp/protocol/version3/packets/019_ssh_fxp_readlink.rb +76 -0
  58. data/lib/hrr_rb_sftp/protocol/version3/packets/020_ssh_fxp_symlink.rb +76 -0
  59. data/lib/hrr_rb_sftp/protocol/version3/packets/101_ssh_fxp_status.rb +25 -0
  60. data/lib/hrr_rb_sftp/protocol/version3/packets/200_ssh_fxp_extended.rb +95 -0
  61. data/lib/hrr_rb_sftp/protocol/version3/packets/201_ssh_fxp_extended_reply.rb +60 -0
  62. data/lib/hrr_rb_sftp/receiver.rb +17 -2
  63. data/lib/hrr_rb_sftp/sender.rb +15 -1
  64. data/lib/hrr_rb_sftp/server.rb +43 -12
  65. data/lib/hrr_rb_sftp/version.rb +5 -1
  66. metadata +54 -47
  67. data/lib/hrr_rb_sftp/protocol/common/data_type.rb +0 -15
  68. data/lib/hrr_rb_sftp/protocol/common/data_type/byte.rb +0 -22
  69. data/lib/hrr_rb_sftp/protocol/common/data_type/extension_pair.rb +0 -23
  70. data/lib/hrr_rb_sftp/protocol/common/data_type/extension_pairs.rb +0 -24
  71. data/lib/hrr_rb_sftp/protocol/common/data_type/string.rb +0 -24
  72. data/lib/hrr_rb_sftp/protocol/common/data_type/uint32.rb +0 -22
  73. data/lib/hrr_rb_sftp/protocol/common/data_type/uint64.rb +0 -22
  74. data/lib/hrr_rb_sftp/protocol/common/packet.rb +0 -11
  75. data/lib/hrr_rb_sftp/protocol/common/packet/001_ssh_fxp_init.rb +0 -18
  76. data/lib/hrr_rb_sftp/protocol/common/packet/002_ssh_fxp_version.rb +0 -19
  77. data/lib/hrr_rb_sftp/protocol/common/packetable.rb +0 -72
  78. data/lib/hrr_rb_sftp/protocol/version1/data_type.rb +0 -11
  79. data/lib/hrr_rb_sftp/protocol/version1/data_type/attrs.rb +0 -54
  80. data/lib/hrr_rb_sftp/protocol/version1/packet.rb +0 -29
  81. data/lib/hrr_rb_sftp/protocol/version1/packet/004_ssh_fxp_close.rb +0 -44
  82. data/lib/hrr_rb_sftp/protocol/version1/packet/005_ssh_fxp_read.rb +0 -53
  83. data/lib/hrr_rb_sftp/protocol/version1/packet/006_ssh_fxp_write.rb +0 -46
  84. data/lib/hrr_rb_sftp/protocol/version1/packet/009_ssh_fxp_setstat.rb +0 -63
  85. data/lib/hrr_rb_sftp/protocol/version1/packet/010_ssh_fxp_fsetstat.rb +0 -48
  86. data/lib/hrr_rb_sftp/protocol/version1/packet/016_ssh_fxp_realpath.rb +0 -30
  87. data/lib/hrr_rb_sftp/protocol/version1/packet/101_ssh_fxp_status.rb +0 -29
  88. data/lib/hrr_rb_sftp/protocol/version1/packet/102_ssh_fxp_handle.rb +0 -19
  89. data/lib/hrr_rb_sftp/protocol/version1/packet/103_ssh_fxp_data.rb +0 -19
  90. data/lib/hrr_rb_sftp/protocol/version1/packet/104_ssh_fxp_name.rb +0 -33
  91. data/lib/hrr_rb_sftp/protocol/version1/packet/105_ssh_fxp_attrs.rb +0 -19
  92. data/lib/hrr_rb_sftp/protocol/version2/data_type.rb +0 -9
  93. data/lib/hrr_rb_sftp/protocol/version2/packet.rb +0 -11
  94. data/lib/hrr_rb_sftp/protocol/version2/packet/018_ssh_fxp_rename.rb +0 -70
  95. data/lib/hrr_rb_sftp/protocol/version3/data_type.rb +0 -9
  96. data/lib/hrr_rb_sftp/protocol/version3/packet.rb +0 -16
  97. data/lib/hrr_rb_sftp/protocol/version3/packet/014_ssh_fxp_mkdir.rb +0 -58
  98. data/lib/hrr_rb_sftp/protocol/version3/packet/019_ssh_fxp_readlink.rb +0 -57
  99. data/lib/hrr_rb_sftp/protocol/version3/packet/020_ssh_fxp_symlink.rb +0 -58
  100. data/lib/hrr_rb_sftp/protocol/version3/packet/101_ssh_fxp_status.rb +0 -31
  101. data/lib/hrr_rb_sftp/protocol/version3/packet/200_ssh_fxp_extended.rb +0 -34
  102. data/lib/hrr_rb_sftp/protocol/version3/packet/201_ssh_fxp_extended_reply.rb +0 -23
@@ -0,0 +1,84 @@
1
+ module HrrRbSftp
2
+ class Protocol
3
+ module Version3
4
+ class Extensions
5
+
6
+ #
7
+ # This class implements hardlink@openssh.com version 1 extension format and responder.
8
+ #
9
+ class HardlinkAtOpensshCom < Extension
10
+
11
+ #
12
+ # Represents hardlink@openssh.com version 1 extension name.
13
+ #
14
+ EXTENSION_NAME = "hardlink@openssh.com"
15
+
16
+ #
17
+ # Represents hardlink@openssh.com version 1 extension data.
18
+ #
19
+ EXTENSION_DATA = "1"
20
+
21
+ #
22
+ # Represents SSH_FXP_EXTENDED packet additional format for hardlink@openssh.com version 1 extension.
23
+ #
24
+ REQUEST_FORMAT = {
25
+ :"extended-request" => {
26
+ "hardlink@openssh.com" => [
27
+ [DataTypes::String, :"oldpath"],
28
+ [DataTypes::String, :"newpath"],
29
+ ],
30
+ },
31
+ }
32
+
33
+ #
34
+ # Responds to SSH_FXP_EXTENDED request with hardlink@openssh.com extended-request.
35
+ #
36
+ # @param request [Hash{Symbol=>Object}] SSH_FXP_EXTENDED request represented in Hash.
37
+ # @return [Hash{Symbol=>Object}] Response represented in Hash. Its type is SSH_FXP_STATUS.
38
+ #
39
+ def respond_to request
40
+ begin
41
+ log_debug { "File.link(#{request[:"oldpath"].inspect}, #{request[:"newpath"].inspect})" }
42
+ File.link(request[:"oldpath"], request[:"newpath"])
43
+ {
44
+ :"type" => Packets::SSH_FXP_STATUS::TYPE,
45
+ :"request-id" => request[:"request-id"],
46
+ :"code" => Packets::SSH_FXP_STATUS::SSH_FX_OK,
47
+ :"error message" => "Success",
48
+ :"language tag" => "",
49
+ }
50
+ rescue Errno::ENOENT => e
51
+ log_debug { e.message }
52
+ {
53
+ :"type" => Packets::SSH_FXP_STATUS::TYPE,
54
+ :"request-id" => request[:"request-id"],
55
+ :"code" => Packets::SSH_FXP_STATUS::SSH_FX_NO_SUCH_FILE,
56
+ :"error message" => "No such file or directory",
57
+ :"language tag" => "",
58
+ }
59
+ rescue Errno::EACCES => e
60
+ log_debug { e.message }
61
+ {
62
+ :"type" => Packets::SSH_FXP_STATUS::TYPE,
63
+ :"request-id" => request[:"request-id"],
64
+ :"code" => Packets::SSH_FXP_STATUS::SSH_FX_PERMISSION_DENIED,
65
+ :"error message" => "Permission denied",
66
+ :"language tag" => "",
67
+ }
68
+ rescue Errno::EEXIST => e
69
+ log_debug { e.message }
70
+ {
71
+ :"type" => Packets::SSH_FXP_STATUS::TYPE,
72
+ :"request-id" => request[:"request-id"],
73
+ :"code" => Packets::SSH_FXP_STATUS::SSH_FX_FAILURE,
74
+ :"error message" => "File exists",
75
+ :"language tag" => "",
76
+ }
77
+ end
78
+ end
79
+ end
80
+ end
81
+ end
82
+ end
83
+ end
84
+
@@ -0,0 +1,132 @@
1
+ module HrrRbSftp
2
+ class Protocol
3
+ module Version3
4
+ class Extensions
5
+
6
+ #
7
+ # This class implements lsetstat@openssh.com version 1 extension format and responder.
8
+ #
9
+ class LsetstatAtOpensshCom < Extension
10
+
11
+ #
12
+ # Represents lsetstat@openssh.com version 1 extension name.
13
+ #
14
+ EXTENSION_NAME = "lsetstat@openssh.com"
15
+
16
+ #
17
+ # Represents lsetstat@openssh.com version 1 extension data.
18
+ #
19
+ EXTENSION_DATA = "1"
20
+
21
+ #
22
+ # Represents SSH_FXP_EXTENDED packet additional format for lsetstat@openssh.com version 1 extension.
23
+ #
24
+ REQUEST_FORMAT = {
25
+ :"extended-request" => {
26
+ "lsetstat@openssh.com" => [
27
+ [DataTypes::String, :"path" ],
28
+ [DataTypes::Attrs, :"attrs"],
29
+ ],
30
+ },
31
+ }
32
+
33
+ #
34
+ # Responds to SSH_FXP_EXTENDED request with lsetstat@openssh.com extended-request.
35
+ #
36
+ # @param request [Hash{Symbol=>Object}] SSH_FXP_EXTENDED request represented in Hash.
37
+ # @return [Hash{Symbol=>Object}] Response represented in Hash. Its type is SSH_FXP_STATUS.
38
+ #
39
+ def respond_to request
40
+ begin
41
+ path = request[:"path"]
42
+ attrs = request[:"attrs"]
43
+ raise BadMessageError, "Invalid file attribute: size" if attrs.has_key?(:"size")
44
+ if attrs.has_key?(:"atime") && attrs.has_key?(:"mtime")
45
+ raise FileLutimeUnsupportedError, "File.lutime is not supported on this Ruby version" unless File.respond_to?(:lutime)
46
+ log_debug { "File.lutime(#{attrs[:"atime"].inspect}, #{attrs[:"mtime"].inspect}, #{path.inspect})" }
47
+ File.lutime(attrs[:"atime"], attrs[:"mtime"], path)
48
+ end
49
+ if attrs.has_key?(:"uid") && attrs.has_key?(:"gid")
50
+ log_debug { "File.lchown(#{attrs[:"uid"].inspect}, #{attrs[:"gid"].inspect}, #{path.inspect})" }
51
+ File.lchown(attrs[:"uid"], attrs[:"gid"], path)
52
+ end
53
+ if attrs.has_key?(:"permissions")
54
+ log_debug { "File.lchmod(#{attrs[:"permissions"].inspect}, #{path.inspect})" }
55
+ File.lchmod(attrs[:"permissions"], path)
56
+ end
57
+ {
58
+ :"type" => Packets::SSH_FXP_STATUS::TYPE,
59
+ :"request-id" => request[:"request-id"],
60
+ :"code" => Packets::SSH_FXP_STATUS::SSH_FX_OK,
61
+ :"error message" => "Success",
62
+ :"language tag" => "",
63
+ }
64
+ rescue BadMessageError => e
65
+ log_debug { e.message }
66
+ {
67
+ :"type" => Packets::SSH_FXP_STATUS::TYPE,
68
+ :"request-id" => request[:"request-id"],
69
+ :"code" => Packets::SSH_FXP_STATUS::SSH_FX_BAD_MESSAGE,
70
+ :"error message" => "Bad message",
71
+ :"language tag" => "",
72
+ }
73
+ rescue FileLutimeUnsupportedError => e
74
+ log_debug { e.message }
75
+ {
76
+ :"type" => Packets::SSH_FXP_STATUS::TYPE,
77
+ :"request-id" => request[:"request-id"],
78
+ :"code" => Packets::SSH_FXP_STATUS::SSH_FX_FAILURE,
79
+ :"error message" => e.message,
80
+ :"language tag" => "",
81
+ }
82
+ rescue Errno::ENOENT => e
83
+ log_debug { e.message }
84
+ {
85
+ :"type" => Packets::SSH_FXP_STATUS::TYPE,
86
+ :"request-id" => request[:"request-id"],
87
+ :"code" => Packets::SSH_FXP_STATUS::SSH_FX_NO_SUCH_FILE,
88
+ :"error message" => "No such file or directory",
89
+ :"language tag" => "",
90
+ }
91
+ rescue Errno::EACCES, Errno::EPERM => e
92
+ log_debug { e.message }
93
+ {
94
+ :"type" => Packets::SSH_FXP_STATUS::TYPE,
95
+ :"request-id" => request[:"request-id"],
96
+ :"code" => Packets::SSH_FXP_STATUS::SSH_FX_PERMISSION_DENIED,
97
+ :"error message" => "Permission denied",
98
+ :"language tag" => "",
99
+ }
100
+ rescue NotImplementedError => e
101
+ log_debug { e.message }
102
+ {
103
+ :"type" => Packets::SSH_FXP_STATUS::TYPE,
104
+ :"request-id" => request[:"request-id"],
105
+ :"code" => Packets::SSH_FXP_STATUS::SSH_FX_FAILURE,
106
+ :"error message" => e.message,
107
+ :"language tag" => "",
108
+ }
109
+ rescue => e
110
+ log_error { [e.backtrace[0], ": ", e.message, " (", e.class.to_s, ")\n\t", e.backtrace[1..-1].join("\n\t")].join }
111
+ {
112
+ :"type" => Packets::SSH_FXP_STATUS::TYPE,
113
+ :"request-id" => request[:"request-id"],
114
+ :"code" => Packets::SSH_FXP_STATUS::SSH_FX_FAILURE,
115
+ :"error message" => e.message,
116
+ :"language tag" => "",
117
+ }
118
+ end
119
+ end
120
+
121
+ class BadMessageError < StandardError
122
+ end
123
+
124
+ class FileLutimeUnsupportedError < StandardError
125
+ end
126
+
127
+ private_constant :BadMessageError, :FileLutimeUnsupportedError
128
+ end
129
+ end
130
+ end
131
+ end
132
+ end
@@ -0,0 +1,76 @@
1
+ module HrrRbSftp
2
+ class Protocol
3
+ module Version3
4
+ class Extensions
5
+
6
+ #
7
+ # This class implements posix-rename@openssh.com version 1 extension format and responder.
8
+ #
9
+ class PosixRenameAtOpensshCom < Extension
10
+
11
+ #
12
+ # Represents posix-rename@openssh.com version 1 extension name.
13
+ #
14
+ EXTENSION_NAME = "posix-rename@openssh.com"
15
+
16
+ #
17
+ # Represents posix-rename@openssh.com version 1 extension data.
18
+ #
19
+ EXTENSION_DATA = "1"
20
+
21
+ #
22
+ # Represents SSH_FXP_EXTENDED packet additional format for posix-rename@openssh.com version 1 extension.
23
+ #
24
+ REQUEST_FORMAT = {
25
+ :"extended-request" => {
26
+ "posix-rename@openssh.com" => [
27
+ [DataTypes::String, :"oldpath"],
28
+ [DataTypes::String, :"newpath"],
29
+ ],
30
+ },
31
+ }
32
+
33
+ #
34
+ # Responds to SSH_FXP_EXTENDED request with posix-rename@openssh.com extended-request.
35
+ #
36
+ # @param request [Hash{Symbol=>Object}] SSH_FXP_EXTENDED request represented in Hash.
37
+ # @return [Hash{Symbol=>Object}] Response represented in Hash. Its type is SSH_FXP_STATUS.
38
+ #
39
+ def respond_to request
40
+ begin
41
+ oldpath = request[:"oldpath"]
42
+ newpath = request[:"newpath"]
43
+ log_debug { "File.rename(#{oldpath.inspect}, #{newpath.inspect})" }
44
+ File.rename(oldpath, newpath)
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
+ rescue Errno::ENOENT => e
53
+ log_debug { e.message }
54
+ {
55
+ :"type" => Packets::SSH_FXP_STATUS::TYPE,
56
+ :"request-id" => request[:"request-id"],
57
+ :"code" => Packets::SSH_FXP_STATUS::SSH_FX_NO_SUCH_FILE,
58
+ :"error message" => "No such file or directory",
59
+ :"language tag" => "",
60
+ }
61
+ rescue Errno::EACCES => e
62
+ log_debug { e.message }
63
+ {
64
+ :"type" => Packets::SSH_FXP_STATUS::TYPE,
65
+ :"request-id" => request[:"request-id"],
66
+ :"code" => Packets::SSH_FXP_STATUS::SSH_FX_PERMISSION_DENIED,
67
+ :"error message" => "Permission denied",
68
+ :"language tag" => "",
69
+ }
70
+ end
71
+ end
72
+ end
73
+ end
74
+ end
75
+ end
76
+ end
@@ -0,0 +1,19 @@
1
+ module HrrRbSftp
2
+ class Protocol
3
+ module Version3
4
+
5
+ #
6
+ # This class implements SFTP protocol version 3 packet types, formats, and responders.
7
+ #
8
+ class Packets < Version2::Packets
9
+ end
10
+ end
11
+ end
12
+ end
13
+
14
+ require "hrr_rb_sftp/protocol/version3/packets/014_ssh_fxp_mkdir"
15
+ require "hrr_rb_sftp/protocol/version3/packets/019_ssh_fxp_readlink"
16
+ require "hrr_rb_sftp/protocol/version3/packets/020_ssh_fxp_symlink"
17
+ require "hrr_rb_sftp/protocol/version3/packets/101_ssh_fxp_status"
18
+ require "hrr_rb_sftp/protocol/version3/packets/200_ssh_fxp_extended"
19
+ require "hrr_rb_sftp/protocol/version3/packets/201_ssh_fxp_extended_reply"
@@ -0,0 +1,75 @@
1
+ module HrrRbSftp
2
+ class Protocol
3
+ module Version3
4
+ class Packets
5
+
6
+ #
7
+ # This class implements SFTP protocol version 3 SSH_FXP_MKDIR packet type, format, and responder.
8
+ #
9
+ class SSH_FXP_MKDIR < Version2::Packets::SSH_FXP_MKDIR
10
+
11
+ #
12
+ # Represents SSH_FXP_MKDIR packet format.
13
+ #
14
+ FORMAT = [
15
+ [DataTypes::Byte, :"type" ],
16
+ [DataTypes::Uint32, :"request-id"],
17
+ [DataTypes::String, :"path" ],
18
+ [DataTypes::Attrs, :"attrs" ],
19
+ ]
20
+
21
+ #
22
+ # Responds to SSH_FXP_MKDIR request.
23
+ #
24
+ # @param request [Hash{Symbol=>Object}] SSH_FXP_MKDIR request represented in Hash.
25
+ # @return [Hash{Symbol=>Object}] Response represented in Hash. Its type is SSH_FXP_STATUS.
26
+ #
27
+ def respond_to request
28
+ begin
29
+ args = [request[:"path"]]
30
+ if request[:"attrs"].has_key?(:"permissions")
31
+ args.push request[:"attrs"][:"permissions"]
32
+ end
33
+ log_debug { "Dir.mkdir(#{args.map(&:inspect).join(", ")})" }
34
+ Dir.mkdir(*args)
35
+ {
36
+ :"type" => Packets::SSH_FXP_STATUS::TYPE,
37
+ :"request-id" => request[:"request-id"],
38
+ :"code" => Packets::SSH_FXP_STATUS::SSH_FX_OK,
39
+ :"error message" => "Success",
40
+ :"language tag" => "",
41
+ }
42
+ rescue Errno::EACCES => e
43
+ log_debug { e.message }
44
+ {
45
+ :"type" => Packets::SSH_FXP_STATUS::TYPE,
46
+ :"request-id" => request[:"request-id"],
47
+ :"code" => Packets::SSH_FXP_STATUS::SSH_FX_PERMISSION_DENIED,
48
+ :"error message" => "Permission denied",
49
+ :"language tag" => "",
50
+ }
51
+ rescue Errno::EEXIST => e
52
+ log_debug { e.message }
53
+ {
54
+ :"type" => Packets::SSH_FXP_STATUS::TYPE,
55
+ :"request-id" => request[:"request-id"],
56
+ :"code" => Packets::SSH_FXP_STATUS::SSH_FX_FAILURE,
57
+ :"error message" => "File exists",
58
+ :"language tag" => "",
59
+ }
60
+ rescue => e
61
+ log_error { [e.backtrace[0], ": ", e.message, " (", e.class.to_s, ")\n\t", e.backtrace[1..-1].join("\n\t")].join }
62
+ {
63
+ :"type" => Packets::SSH_FXP_STATUS::TYPE,
64
+ :"request-id" => request[:"request-id"],
65
+ :"code" => Packets::SSH_FXP_STATUS::SSH_FX_FAILURE,
66
+ :"error message" => e.message,
67
+ :"language tag" => "",
68
+ }
69
+ end
70
+ end
71
+ end
72
+ end
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,76 @@
1
+ module HrrRbSftp
2
+ class Protocol
3
+ module Version3
4
+ class Packets
5
+
6
+ #
7
+ # This class implements SFTP protocol version 1 SSH_FXP_READLINK packet type, format, and responder.
8
+ #
9
+ class SSH_FXP_READLINK < Packets::Packet
10
+
11
+ #
12
+ # Represents SSH_FXP_READLINK packet type.
13
+ #
14
+ TYPE = 19
15
+
16
+ #
17
+ # Represents SSH_FXP_READLINK packet format.
18
+ #
19
+ FORMAT = [
20
+ [DataTypes::Byte, :"type" ],
21
+ [DataTypes::Uint32, :"request-id"],
22
+ [DataTypes::String, :"path" ],
23
+ ]
24
+
25
+ #
26
+ # Responds to SSH_FXP_READLINK request.
27
+ #
28
+ # @param request [Hash{Symbol=>Object}] SSH_FXP_READLINK 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
+ log_debug { "realpath = File.realpath(#{request[:"path"].inspect})" }
34
+ realpath = File.realpath(request[:"path"])
35
+ {
36
+ :"type" => Packets::SSH_FXP_NAME::TYPE,
37
+ :"request-id" => request[:"request-id"],
38
+ :"count" => 1,
39
+ :"filename[0]" => realpath,
40
+ :"longname[0]" => realpath,
41
+ :"attrs[0]" => {},
42
+ }
43
+ rescue Errno::ENOENT => e
44
+ log_debug { e.message }
45
+ {
46
+ :"type" => Packets::SSH_FXP_STATUS::TYPE,
47
+ :"request-id" => request[:"request-id"],
48
+ :"code" => Packets::SSH_FXP_STATUS::SSH_FX_NO_SUCH_FILE,
49
+ :"error message" => "No such file or directory",
50
+ :"language tag" => "",
51
+ }
52
+ rescue Errno::EACCES => e
53
+ log_debug { e.message }
54
+ {
55
+ :"type" => Packets::SSH_FXP_STATUS::TYPE,
56
+ :"request-id" => request[:"request-id"],
57
+ :"code" => Packets::SSH_FXP_STATUS::SSH_FX_PERMISSION_DENIED,
58
+ :"error message" => "Permission denied",
59
+ :"language tag" => "",
60
+ }
61
+ rescue => e
62
+ log_error { [e.backtrace[0], ": ", e.message, " (", e.class.to_s, ")\n\t", e.backtrace[1..-1].join("\n\t")].join }
63
+ {
64
+ :"type" => Packets::SSH_FXP_STATUS::TYPE,
65
+ :"request-id" => request[:"request-id"],
66
+ :"code" => Packets::SSH_FXP_STATUS::SSH_FX_FAILURE,
67
+ :"error message" => e.message,
68
+ :"language tag" => "",
69
+ }
70
+ end
71
+ end
72
+ end
73
+ end
74
+ end
75
+ end
76
+ end