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
@@ -1,73 +1,88 @@
1
1
  module HrrRbSftp
2
2
  class Protocol
3
- class Version1
4
- module Packet
5
- class SSH_FXP_OPEN
6
- include Common::Packetable
3
+ module Version1
4
+ class Packets
7
5
 
6
+ #
7
+ # This class implements SFTP protocol version 1 SSH_FXP_OPEN packet type, format, and responder.
8
+ #
9
+ class SSH_FXP_OPEN < Packet
10
+
11
+ #
12
+ # Represents SSH_FXP_OPEN packet type.
13
+ #
8
14
  TYPE = 3
9
15
 
16
+ #
17
+ # Represents SSH_FXP_OPEN packet format.
18
+ #
10
19
  FORMAT = [
11
- [DataType::Byte, :"type" ],
12
- [DataType::Uint32, :"request-id"],
13
- [DataType::String, :"filename" ],
14
- [DataType::Uint32, :"pflags" ],
15
- [DataType::Attrs, :"attrs" ],
20
+ [DataTypes::Byte, :"type" ],
21
+ [DataTypes::Uint32, :"request-id"],
22
+ [DataTypes::String, :"filename" ],
23
+ [DataTypes::Uint32, :"pflags" ],
24
+ [DataTypes::Attrs, :"attrs" ],
16
25
  ]
17
26
 
27
+ #
28
+ # Represents SSH_FXF_READ flag.
29
+ #
18
30
  SSH_FXF_READ = 0x00000001
31
+
32
+ #
33
+ # Represents SSH_FXF_WRITE flag.
34
+ #
19
35
  SSH_FXF_WRITE = 0x00000002
36
+
37
+ #
38
+ # Represents SSH_FXF_APPEND flag.
39
+ #
20
40
  SSH_FXF_APPEND = 0x00000004
41
+
42
+ #
43
+ # Represents SSH_FXF_CREAT flag.
44
+ #
21
45
  SSH_FXF_CREAT = 0x00000008
22
- SSH_FXF_TRUNC = 0x00000010
23
- SSH_FXF_EXCL = 0x00000020
24
46
 
25
- class Error < StandardError
26
- end
47
+ #
48
+ # Represents SSH_FXF_TRUNC flag.
49
+ #
50
+ SSH_FXF_TRUNC = 0x00000010
27
51
 
28
- def convert_pflags_to_flags pflags
29
- flags = 0
30
- if ((pflags & SSH_FXF_READ) == SSH_FXF_READ) && ((pflags & SSH_FXF_WRITE) == SSH_FXF_WRITE)
31
- flags |= ::File::RDWR
32
- elsif (pflags & SSH_FXF_READ) == SSH_FXF_READ
33
- flags |= ::File::RDONLY
34
- elsif (pflags & SSH_FXF_WRITE) == SSH_FXF_WRITE
35
- flags |= ::File::WRONLY
36
- else
37
- raise Error, "At least SSH_FXF_READ or SSH_FXF_READ must be specified"
38
- end
39
- if (pflags & SSH_FXF_APPEND) == SSH_FXF_APPEND
40
- flags |= ::File::APPEND
41
- end
42
- if (pflags & SSH_FXF_CREAT) == SSH_FXF_CREAT
43
- flags |= ::File::CREAT
44
- flags |= ::File::TRUNC if (pflags & SSH_FXF_TRUNC) == SSH_FXF_TRUNC
45
- flags |= ::File::EXCL if (pflags & SSH_FXF_EXCL ) == SSH_FXF_EXCL
46
- elsif (pflags & SSH_FXF_TRUNC) == SSH_FXF_TRUNC
47
- raise Error, "SSH_FXF_CREAT MUST also be specified when SSH_FXF_TRUNC is specified"
48
- elsif (pflags & SSH_FXF_EXCL) == SSH_FXF_EXCL
49
- raise Error, "SSH_FXF_CREAT MUST also be specified when SSH_FXF_EXCL is specified"
50
- end
51
- flags |= ::File::BINARY
52
- flags
53
- end
52
+ #
53
+ # Represents SSH_FXF_EXCL flag.
54
+ #
55
+ SSH_FXF_EXCL = 0x00000020
54
56
 
57
+ #
58
+ # Responds to SSH_FXP_OPEN request.
59
+ #
60
+ # @param request [Hash{Symbol=>Object}] SSH_FXP_OPEN request represented in Hash.
61
+ # Only permissions attribute is taken care of.
62
+ # When attrs field contains attributes other than permissions are ignored
63
+ # and they are expected to be taken care of by subsequent SSH_FXP_SETSTAT and/or SSH_FXP_FSETSTAT requests.
64
+ # @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.
65
+ #
55
66
  def respond_to request
56
67
  begin
57
68
  flags = convert_pflags_to_flags request[:"pflags"]
58
69
  args = [request[:"filename"], flags]
59
- if request[:"attrs"].has_key?(:"permissions")
70
+ if (flags & ::File::CREAT == ::File::CREAT) && request[:"attrs"].has_key?(:"permissions")
60
71
  args.push request[:"attrs"][:"permissions"]
61
72
  end
73
+ log_debug { "file = File.open(#{args.map(&:inspect).join(", ")})" }
62
74
  file = ::File.open(*args)
75
+ log_debug { "handle = #{file.object_id.to_s(16).inspect}" }
63
76
  handle = file.object_id.to_s(16)
64
- @handles[handle] = file
77
+ log_debug { "handles[#{handle.inspect}] = file" }
78
+ handles[handle] = file
65
79
  {
66
80
  :"type" => SSH_FXP_HANDLE::TYPE,
67
81
  :"request-id" => request[:"request-id"],
68
82
  :"handle" => handle,
69
83
  }
70
84
  rescue Error => e
85
+ log_debug { e.message }
71
86
  {
72
87
  :"type" => SSH_FXP_STATUS::TYPE,
73
88
  :"request-id" => request[:"request-id"],
@@ -75,7 +90,8 @@ module HrrRbSftp
75
90
  :"error message" => e.message,
76
91
  :"language tag" => "",
77
92
  }
78
- rescue Errno::ENOENT
93
+ rescue Errno::ENOENT => e
94
+ log_debug { e.message }
79
95
  {
80
96
  :"type" => SSH_FXP_STATUS::TYPE,
81
97
  :"request-id" => request[:"request-id"],
@@ -83,7 +99,8 @@ module HrrRbSftp
83
99
  :"error message" => "No such file or directory",
84
100
  :"language tag" => "",
85
101
  }
86
- rescue Errno::EACCES
102
+ rescue Errno::EACCES => e
103
+ log_debug { e.message }
87
104
  {
88
105
  :"type" => SSH_FXP_STATUS::TYPE,
89
106
  :"request-id" => request[:"request-id"],
@@ -102,6 +119,40 @@ module HrrRbSftp
102
119
  }
103
120
  end
104
121
  end
122
+
123
+ class Error < StandardError
124
+ end
125
+
126
+ private_constant :Error
127
+
128
+ private
129
+
130
+ def convert_pflags_to_flags pflags
131
+ flags = 0
132
+ if ((pflags & SSH_FXF_READ) == SSH_FXF_READ) && ((pflags & SSH_FXF_WRITE) == SSH_FXF_WRITE)
133
+ flags |= ::File::RDWR
134
+ elsif (pflags & SSH_FXF_READ) == SSH_FXF_READ
135
+ flags |= ::File::RDONLY
136
+ elsif (pflags & SSH_FXF_WRITE) == SSH_FXF_WRITE
137
+ flags |= ::File::WRONLY
138
+ else
139
+ raise Error, "At least SSH_FXF_READ or SSH_FXF_READ must be specified"
140
+ end
141
+ if (pflags & SSH_FXF_APPEND) == SSH_FXF_APPEND
142
+ flags |= ::File::APPEND
143
+ end
144
+ if (pflags & SSH_FXF_CREAT) == SSH_FXF_CREAT
145
+ flags |= ::File::CREAT
146
+ flags |= ::File::TRUNC if (pflags & SSH_FXF_TRUNC) == SSH_FXF_TRUNC
147
+ flags |= ::File::EXCL if (pflags & SSH_FXF_EXCL ) == SSH_FXF_EXCL
148
+ elsif (pflags & SSH_FXF_TRUNC) == SSH_FXF_TRUNC
149
+ raise Error, "SSH_FXF_CREAT MUST also be specified when SSH_FXF_TRUNC is specified"
150
+ elsif (pflags & SSH_FXF_EXCL) == SSH_FXF_EXCL
151
+ raise Error, "SSH_FXF_CREAT MUST also be specified when SSH_FXF_EXCL is specified"
152
+ end
153
+ flags |= ::File::BINARY
154
+ flags
155
+ end
105
156
  end
106
157
  end
107
158
  end
@@ -0,0 +1,61 @@
1
+ module HrrRbSftp
2
+ class Protocol
3
+ module Version1
4
+ class Packets
5
+
6
+ #
7
+ # This class implements SFTP protocol version 1 SSH_FXP_CLOSE packet type, format, and responder.
8
+ #
9
+ class SSH_FXP_CLOSE < Packet
10
+
11
+ #
12
+ # Represents SSH_FXP_CLOSE packet type.
13
+ #
14
+ TYPE = 4
15
+
16
+ #
17
+ # Represents SSH_FXP_CLOSE packet format.
18
+ #
19
+ FORMAT = [
20
+ [DataTypes::Byte, :"type" ],
21
+ [DataTypes::Uint32, :"request-id"],
22
+ [DataTypes::String, :"handle" ],
23
+ ]
24
+
25
+ #
26
+ # Responds to SSH_FXP_CLOSE request.
27
+ #
28
+ # @param request [Hash{Symbol=>Object}] SSH_FXP_CLOSE request represented in Hash.
29
+ # @return [Hash{Symbol=>Object}] Response represented in Hash. 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
+ handle = request[:"handle"]
35
+ log_debug { "handles[#{handle.inspect}].close" }
36
+ handles[handle].close rescue nil
37
+ log_debug { "handles.delete(#{handle.inspect})" }
38
+ handles.delete(handle)
39
+ {
40
+ :"type" => SSH_FXP_STATUS::TYPE,
41
+ :"request-id" => request[:"request-id"],
42
+ :"code" => SSH_FXP_STATUS::SSH_FX_OK,
43
+ :"error message" => "Success",
44
+ :"language tag" => "",
45
+ }
46
+ rescue => e
47
+ log_error { [e.backtrace[0], ": ", e.message, " (", e.class.to_s, ")\n\t", e.backtrace[1..-1].join("\n\t")].join }
48
+ {
49
+ :"type" => SSH_FXP_STATUS::TYPE,
50
+ :"request-id" => request[:"request-id"],
51
+ :"code" => SSH_FXP_STATUS::SSH_FX_FAILURE,
52
+ :"error message" => e.message,
53
+ :"language tag" => "",
54
+ }
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,72 @@
1
+ module HrrRbSftp
2
+ class Protocol
3
+ module Version1
4
+ class Packets
5
+
6
+ #
7
+ # This class implements SFTP protocol version 1 SSH_FXP_READ packet type, format, and responder.
8
+ #
9
+ class SSH_FXP_READ < Packet
10
+
11
+ #
12
+ # Represents SSH_FXP_READ packet type.
13
+ #
14
+ TYPE = 5
15
+
16
+ #
17
+ # Represents SSH_FXP_READ packet format.
18
+ #
19
+ FORMAT = [
20
+ [DataTypes::Byte, :"type" ],
21
+ [DataTypes::Uint32, :"request-id"],
22
+ [DataTypes::String, :"handle" ],
23
+ [DataTypes::Uint64, :"offset" ],
24
+ [DataTypes::Uint32, :"len" ],
25
+ ]
26
+
27
+ #
28
+ # Responds to SSH_FXP_READ request.
29
+ #
30
+ # @param request [Hash{Symbol=>Object}] SSH_FXP_READ request represented in Hash.
31
+ # @return [Hash{Symbol=>Object}] Response represented in Hash. In case of success, its type is SSH_FXP_DATA. In other cases, its type is SSH_FXP_STATUS.
32
+ #
33
+ def respond_to request
34
+ begin
35
+ raise "Specified handle does not exist" unless handles.has_key?(request[:"handle"])
36
+ log_debug { "file = handles[#{request[:"handle"].inspect}]" }
37
+ file = handles[request[:"handle"]]
38
+ log_debug { "file.pos = #{request[:"offset"].inspect}" }
39
+ file.pos = request[:"offset"]
40
+ unless file.eof?
41
+ log_debug { "data = file.read(#{request[:"len"].inspect})" }
42
+ data = file.read(request[:"len"])
43
+ {
44
+ :"type" => SSH_FXP_DATA::TYPE,
45
+ :"request-id" => request[:"request-id"],
46
+ :"data" => data,
47
+ }
48
+ else
49
+ {
50
+ :"type" => SSH_FXP_STATUS::TYPE,
51
+ :"request-id" => request[:"request-id"],
52
+ :"code" => SSH_FXP_STATUS::SSH_FX_EOF,
53
+ :"error message" => "End of file",
54
+ :"language tag" => "",
55
+ }
56
+ end
57
+ rescue => e
58
+ log_error { [e.backtrace[0], ": ", e.message, " (", e.class.to_s, ")\n\t", e.backtrace[1..-1].join("\n\t")].join }
59
+ {
60
+ :"type" => SSH_FXP_STATUS::TYPE,
61
+ :"request-id" => request[:"request-id"],
62
+ :"code" => SSH_FXP_STATUS::SSH_FX_FAILURE,
63
+ :"error message" => e.message,
64
+ :"language tag" => "",
65
+ }
66
+ end
67
+ end
68
+ end
69
+ end
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,64 @@
1
+ module HrrRbSftp
2
+ class Protocol
3
+ module Version1
4
+ class Packets
5
+
6
+ #
7
+ # This class implements SFTP protocol version 1 SSH_FXP_WRITE packet type, format, and responder.
8
+ #
9
+ class SSH_FXP_WRITE < Packet
10
+
11
+ #
12
+ # Represents SSH_FXP_WRITE packet type.
13
+ #
14
+ TYPE = 6
15
+
16
+ #
17
+ # Represents SSH_FXP_WRITE packet format.
18
+ #
19
+ FORMAT = [
20
+ [DataTypes::Byte, :"type" ],
21
+ [DataTypes::Uint32, :"request-id"],
22
+ [DataTypes::String, :"handle" ],
23
+ [DataTypes::Uint64, :"offset" ],
24
+ [DataTypes::String, :"data" ],
25
+ ]
26
+
27
+ #
28
+ # Responds to SSH_FXP_WRITE request.
29
+ #
30
+ # @param request [Hash{Symbol=>Object}] SSH_FXP_WRITE request represented in Hash.
31
+ # @return [Hash{Symbol=>Object}] Response represented in Hash. Its type is SSH_FXP_STATUS.
32
+ #
33
+ def respond_to request
34
+ begin
35
+ raise "Specified handle does not exist" unless handles.has_key?(request[:"handle"])
36
+ log_debug { "file = handles[#{request[:"handle"].inspect}]" }
37
+ file = handles[request[:"handle"]]
38
+ log_debug { "file.pos = #{request[:"offset"].inspect}" }
39
+ file.pos = request[:"offset"]
40
+ log_debug { "file.write(#{request[:"data"].inspect})" }
41
+ file.write(request[:"data"])
42
+ {
43
+ :"type" => SSH_FXP_STATUS::TYPE,
44
+ :"request-id" => request[:"request-id"],
45
+ :"code" => SSH_FXP_STATUS::SSH_FX_OK,
46
+ :"error message" => "Success",
47
+ :"language tag" => "",
48
+ }
49
+ rescue => e
50
+ log_error { [e.backtrace[0], ": ", e.message, " (", e.class.to_s, ")\n\t", e.backtrace[1..-1].join("\n\t")].join }
51
+ {
52
+ :"type" => SSH_FXP_STATUS::TYPE,
53
+ :"request-id" => request[:"request-id"],
54
+ :"code" => SSH_FXP_STATUS::SSH_FX_FAILURE,
55
+ :"error message" => e.message,
56
+ :"language tag" => "",
57
+ }
58
+ end
59
+ end
60
+ end
61
+ end
62
+ end
63
+ end
64
+ end
@@ -1,20 +1,36 @@
1
1
  module HrrRbSftp
2
2
  class Protocol
3
- class Version1
4
- module Packet
5
- class SSH_FXP_LSTAT
6
- include Common::Packetable
3
+ module Version1
4
+ class Packets
7
5
 
6
+ #
7
+ # This class implements SFTP protocol version 1 SSH_FXP_LSTAT packet type, format, and responder.
8
+ #
9
+ class SSH_FXP_LSTAT < Packet
10
+
11
+ #
12
+ # Represents SSH_FXP_LSTAT packet type.
13
+ #
8
14
  TYPE = 7
9
15
 
16
+ #
17
+ # Represents SSH_FXP_LSTAT packet format.
18
+ #
10
19
  FORMAT = [
11
- [DataType::Byte, :"type" ],
12
- [DataType::Uint32, :"request-id"],
13
- [DataType::String, :"path" ],
20
+ [DataTypes::Byte, :"type" ],
21
+ [DataTypes::Uint32, :"request-id"],
22
+ [DataTypes::String, :"path" ],
14
23
  ]
15
24
 
25
+ #
26
+ # Responds to SSH_FXP_LSTAT request.
27
+ #
28
+ # @param request [Hash{Symbol=>Object}] SSH_FXP_LSTAT 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
33
+ log_debug { "File.lstat(#{request[:"path"].inspect})" }
18
34
  stat = File.lstat(request[:"path"])
19
35
  attrs = Hash.new
20
36
  attrs[:"size"] = stat.size if stat.size
@@ -28,7 +44,8 @@ module HrrRbSftp
28
44
  :"request-id" => request[:"request-id"],
29
45
  :"attrs" => attrs,
30
46
  }
31
- rescue Errno::ENOENT
47
+ rescue Errno::ENOENT => e
48
+ log_debug { e.message }
32
49
  {
33
50
  :"type" => SSH_FXP_STATUS::TYPE,
34
51
  :"request-id" => request[:"request-id"],
@@ -36,7 +53,8 @@ module HrrRbSftp
36
53
  :"error message" => "No such file or directory",
37
54
  :"language tag" => "",
38
55
  }
39
- rescue Errno::EACCES
56
+ rescue Errno::EACCES => e
57
+ log_debug { e.message }
40
58
  {
41
59
  :"type" => SSH_FXP_STATUS::TYPE,
42
60
  :"request-id" => request[:"request-id"],