hrr_rb_sftp 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
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"],