hrr_rb_sftp 0.1.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 (72) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +18 -0
  3. data/.rspec +3 -0
  4. data/.travis.yml +25 -0
  5. data/CODE_OF_CONDUCT.md +74 -0
  6. data/Gemfile +7 -0
  7. data/LICENSE.txt +21 -0
  8. data/README.md +135 -0
  9. data/Rakefile +6 -0
  10. data/bin/console +14 -0
  11. data/bin/setup +8 -0
  12. data/demo/hrr_rb_sftp_server.rb +23 -0
  13. data/demo/instantiate_hrr_rb_sftp_server.rb +67 -0
  14. data/demo/spawn_hrr_rb_sftp_server.rb +66 -0
  15. data/hrr_rb_sftp.gemspec +26 -0
  16. data/lib/hrr_rb_sftp.rb +13 -0
  17. data/lib/hrr_rb_sftp/loggable.rb +41 -0
  18. data/lib/hrr_rb_sftp/protocol.rb +62 -0
  19. data/lib/hrr_rb_sftp/protocol/common.rb +10 -0
  20. data/lib/hrr_rb_sftp/protocol/common/data_type.rb +15 -0
  21. data/lib/hrr_rb_sftp/protocol/common/data_type/byte.rb +22 -0
  22. data/lib/hrr_rb_sftp/protocol/common/data_type/extension_pair.rb +23 -0
  23. data/lib/hrr_rb_sftp/protocol/common/data_type/extension_pairs.rb +24 -0
  24. data/lib/hrr_rb_sftp/protocol/common/data_type/string.rb +24 -0
  25. data/lib/hrr_rb_sftp/protocol/common/data_type/uint32.rb +22 -0
  26. data/lib/hrr_rb_sftp/protocol/common/data_type/uint64.rb +22 -0
  27. data/lib/hrr_rb_sftp/protocol/common/packet.rb +11 -0
  28. data/lib/hrr_rb_sftp/protocol/common/packet/001_ssh_fxp_init.rb +18 -0
  29. data/lib/hrr_rb_sftp/protocol/common/packet/002_ssh_fxp_version.rb +19 -0
  30. data/lib/hrr_rb_sftp/protocol/common/packetable.rb +72 -0
  31. data/lib/hrr_rb_sftp/protocol/version1.rb +10 -0
  32. data/lib/hrr_rb_sftp/protocol/version1/data_type.rb +11 -0
  33. data/lib/hrr_rb_sftp/protocol/version1/data_type/attrs.rb +54 -0
  34. data/lib/hrr_rb_sftp/protocol/version1/packet.rb +29 -0
  35. data/lib/hrr_rb_sftp/protocol/version1/packet/003_ssh_fxp_open.rb +109 -0
  36. data/lib/hrr_rb_sftp/protocol/version1/packet/004_ssh_fxp_close.rb +44 -0
  37. data/lib/hrr_rb_sftp/protocol/version1/packet/005_ssh_fxp_read.rb +53 -0
  38. data/lib/hrr_rb_sftp/protocol/version1/packet/006_ssh_fxp_write.rb +46 -0
  39. data/lib/hrr_rb_sftp/protocol/version1/packet/007_ssh_fxp_lstat.rb +62 -0
  40. data/lib/hrr_rb_sftp/protocol/version1/packet/008_ssh_fxp_fstat.rb +48 -0
  41. data/lib/hrr_rb_sftp/protocol/version1/packet/009_ssh_fxp_setstat.rb +63 -0
  42. data/lib/hrr_rb_sftp/protocol/version1/packet/010_ssh_fxp_fsetstat.rb +48 -0
  43. data/lib/hrr_rb_sftp/protocol/version1/packet/011_ssh_fxp_opendir.rb +65 -0
  44. data/lib/hrr_rb_sftp/protocol/version1/packet/012_ssh_fxp_readdir.rb +134 -0
  45. data/lib/hrr_rb_sftp/protocol/version1/packet/013_ssh_fxp_remove.rb +57 -0
  46. data/lib/hrr_rb_sftp/protocol/version1/packet/014_ssh_fxp_mkdir.rb +57 -0
  47. data/lib/hrr_rb_sftp/protocol/version1/packet/015_ssh_fxp_rmdir.rb +73 -0
  48. data/lib/hrr_rb_sftp/protocol/version1/packet/016_ssh_fxp_realpath.rb +30 -0
  49. data/lib/hrr_rb_sftp/protocol/version1/packet/017_ssh_fxp_stat.rb +62 -0
  50. data/lib/hrr_rb_sftp/protocol/version1/packet/101_ssh_fxp_status.rb +29 -0
  51. data/lib/hrr_rb_sftp/protocol/version1/packet/102_ssh_fxp_handle.rb +19 -0
  52. data/lib/hrr_rb_sftp/protocol/version1/packet/103_ssh_fxp_data.rb +19 -0
  53. data/lib/hrr_rb_sftp/protocol/version1/packet/104_ssh_fxp_name.rb +33 -0
  54. data/lib/hrr_rb_sftp/protocol/version1/packet/105_ssh_fxp_attrs.rb +19 -0
  55. data/lib/hrr_rb_sftp/protocol/version2.rb +10 -0
  56. data/lib/hrr_rb_sftp/protocol/version2/data_type.rb +9 -0
  57. data/lib/hrr_rb_sftp/protocol/version2/packet.rb +11 -0
  58. data/lib/hrr_rb_sftp/protocol/version2/packet/018_ssh_fxp_rename.rb +70 -0
  59. data/lib/hrr_rb_sftp/protocol/version3.rb +10 -0
  60. data/lib/hrr_rb_sftp/protocol/version3/data_type.rb +9 -0
  61. data/lib/hrr_rb_sftp/protocol/version3/packet.rb +16 -0
  62. data/lib/hrr_rb_sftp/protocol/version3/packet/014_ssh_fxp_mkdir.rb +58 -0
  63. data/lib/hrr_rb_sftp/protocol/version3/packet/019_ssh_fxp_readlink.rb +57 -0
  64. data/lib/hrr_rb_sftp/protocol/version3/packet/020_ssh_fxp_symlink.rb +58 -0
  65. data/lib/hrr_rb_sftp/protocol/version3/packet/101_ssh_fxp_status.rb +31 -0
  66. data/lib/hrr_rb_sftp/protocol/version3/packet/200_ssh_fxp_extended.rb +34 -0
  67. data/lib/hrr_rb_sftp/protocol/version3/packet/201_ssh_fxp_extended_reply.rb +23 -0
  68. data/lib/hrr_rb_sftp/receiver.rb +22 -0
  69. data/lib/hrr_rb_sftp/sender.rb +13 -0
  70. data/lib/hrr_rb_sftp/server.rb +96 -0
  71. data/lib/hrr_rb_sftp/version.rb +3 -0
  72. metadata +114 -0
@@ -0,0 +1,63 @@
1
+ module HrrRbSftp
2
+ class Protocol
3
+ class Version1
4
+ module Packet
5
+ class SSH_FXP_SETSTAT
6
+ include Common::Packetable
7
+
8
+ TYPE = 9
9
+
10
+ FORMAT = [
11
+ [DataType::Byte, :"type" ],
12
+ [DataType::Uint32, :"request-id"],
13
+ [DataType::String, :"path" ],
14
+ [DataType::Attrs, :"attrs" ],
15
+ ]
16
+
17
+ def respond_to request
18
+ begin
19
+ path = request[:"path"]
20
+ attrs = request[:"attrs"]
21
+ FileUtils.chmod(attrs[:"permissions"], path) if attrs.has_key?(:"permissions")
22
+ File.utime(attrs[:"atime"], attrs[:"mtime"], path) if attrs.has_key?(:"atime") && attrs.has_key?(:"mtime")
23
+ FileUtils.chown(attrs[:"uid"], attrs[:"gid"], path) if attrs.has_key?(:"uid") && attrs.has_key?(:"gid")
24
+ File.truncate(path, attrs[:"size"]) if attrs.has_key?(:"size")
25
+ {
26
+ :"type" => SSH_FXP_STATUS::TYPE,
27
+ :"request-id" => request[:"request-id"],
28
+ :"code" => SSH_FXP_STATUS::SSH_FX_OK,
29
+ :"error message" => "Success",
30
+ :"language tag" => "",
31
+ }
32
+ rescue Errno::ENOENT
33
+ {
34
+ :"type" => SSH_FXP_STATUS::TYPE,
35
+ :"request-id" => request[:"request-id"],
36
+ :"code" => SSH_FXP_STATUS::SSH_FX_NO_SUCH_FILE,
37
+ :"error message" => "No such file or directory",
38
+ :"language tag" => "",
39
+ }
40
+ rescue Errno::EACCES
41
+ {
42
+ :"type" => SSH_FXP_STATUS::TYPE,
43
+ :"request-id" => request[:"request-id"],
44
+ :"code" => SSH_FXP_STATUS::SSH_FX_PERMISSION_DENIED,
45
+ :"error message" => "Permission denied",
46
+ :"language tag" => "",
47
+ }
48
+ rescue => e
49
+ log_error { [e.backtrace[0], ": ", e.message, " (", e.class.to_s, ")\n\t", e.backtrace[1..-1].join("\n\t")].join }
50
+ {
51
+ :"type" => SSH_FXP_STATUS::TYPE,
52
+ :"request-id" => request[:"request-id"],
53
+ :"code" => SSH_FXP_STATUS::SSH_FX_FAILURE,
54
+ :"error message" => e.message,
55
+ :"language tag" => "",
56
+ }
57
+ end
58
+ end
59
+ end
60
+ end
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,48 @@
1
+ module HrrRbSftp
2
+ class Protocol
3
+ class Version1
4
+ module Packet
5
+ class SSH_FXP_FSETSTAT
6
+ include Common::Packetable
7
+
8
+ TYPE = 10
9
+
10
+ FORMAT = [
11
+ [DataType::Byte, :"type" ],
12
+ [DataType::Uint32, :"request-id"],
13
+ [DataType::String, :"handle" ],
14
+ [DataType::Attrs, :"attrs" ],
15
+ ]
16
+
17
+ def respond_to request
18
+ begin
19
+ raise "Specified handle does not exist" unless @handles.has_key?(request[:"handle"])
20
+ file = @handles[request[:"handle"]]
21
+ attrs = request[:"attrs"]
22
+ file.chmod(attrs[:"permissions"]) if attrs.has_key?(:"permissions")
23
+ File.utime(attrs[:"atime"], attrs[:"mtime"], file.path) if attrs.has_key?(:"atime") && attrs.has_key?(:"mtime")
24
+ file.chown(attrs[:"uid"], attrs[:"gid"]) if attrs.has_key?(:"uid") && attrs.has_key?(:"gid")
25
+ file.truncate(attrs[:"size"]) if attrs.has_key?(:"size")
26
+ {
27
+ :"type" => SSH_FXP_STATUS::TYPE,
28
+ :"request-id" => request[:"request-id"],
29
+ :"code" => SSH_FXP_STATUS::SSH_FX_OK,
30
+ :"error message" => "Success",
31
+ :"language tag" => "",
32
+ }
33
+ rescue => e
34
+ log_error { [e.backtrace[0], ": ", e.message, " (", e.class.to_s, ")\n\t", e.backtrace[1..-1].join("\n\t")].join }
35
+ {
36
+ :"type" => SSH_FXP_STATUS::TYPE,
37
+ :"request-id" => request[:"request-id"],
38
+ :"code" => SSH_FXP_STATUS::SSH_FX_FAILURE,
39
+ :"error message" => e.message,
40
+ :"language tag" => "",
41
+ }
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,65 @@
1
+ module HrrRbSftp
2
+ class Protocol
3
+ class Version1
4
+ module Packet
5
+ class SSH_FXP_OPENDIR
6
+ include Common::Packetable
7
+
8
+ TYPE = 11
9
+
10
+ FORMAT = [
11
+ [DataType::Byte, :"type" ],
12
+ [DataType::Uint32, :"request-id"],
13
+ [DataType::String, :"path" ],
14
+ ]
15
+
16
+ def respond_to request
17
+ begin
18
+ dir = ::Dir.open(request[:"path"])
19
+ handle = dir.object_id.to_s(16)
20
+ @handles[handle] = dir
21
+ {
22
+ :"type" => SSH_FXP_HANDLE::TYPE,
23
+ :"request-id" => request[:"request-id"],
24
+ :"handle" => handle,
25
+ }
26
+ rescue Errno::ENOENT
27
+ {
28
+ :"type" => SSH_FXP_STATUS::TYPE,
29
+ :"request-id" => request[:"request-id"],
30
+ :"code" => SSH_FXP_STATUS::SSH_FX_NO_SUCH_FILE,
31
+ :"error message" => "No such file or directory",
32
+ :"language tag" => "",
33
+ }
34
+ rescue Errno::EACCES
35
+ {
36
+ :"type" => SSH_FXP_STATUS::TYPE,
37
+ :"request-id" => request[:"request-id"],
38
+ :"code" => SSH_FXP_STATUS::SSH_FX_PERMISSION_DENIED,
39
+ :"error message" => "Permission denied",
40
+ :"language tag" => "",
41
+ }
42
+ rescue Errno::ENOTDIR
43
+ {
44
+ :"type" => SSH_FXP_STATUS::TYPE,
45
+ :"request-id" => request[:"request-id"],
46
+ :"code" => SSH_FXP_STATUS::SSH_FX_FAILURE,
47
+ :"error message" => "Not a directory",
48
+ :"language tag" => "",
49
+ }
50
+ rescue => e
51
+ log_error { [e.backtrace[0], ": ", e.message, " (", e.class.to_s, ")\n\t", e.backtrace[1..-1].join("\n\t")].join }
52
+ {
53
+ :"type" => SSH_FXP_STATUS::TYPE,
54
+ :"request-id" => request[:"request-id"],
55
+ :"code" => SSH_FXP_STATUS::SSH_FX_FAILURE,
56
+ :"error message" => e.message,
57
+ :"language tag" => "",
58
+ }
59
+ end
60
+ end
61
+ end
62
+ end
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,134 @@
1
+ module HrrRbSftp
2
+ class Protocol
3
+ class Version1
4
+ module Packet
5
+ class SSH_FXP_READDIR
6
+ include Common::Packetable
7
+
8
+ TYPE = 12
9
+
10
+ FORMAT = [
11
+ [DataType::Byte, :"type" ],
12
+ [DataType::Uint32, :"request-id"],
13
+ [DataType::String, :"handle" ],
14
+ ]
15
+
16
+ def longname_permissions stat
17
+ s = ::String.new
18
+ s += case stat.mode & 0170000
19
+ when 0140000 then "s"
20
+ when 0120000 then "l"
21
+ when 0100000 then "-"
22
+ when 0060000 then "b"
23
+ when 0040000 then "d"
24
+ when 0020000 then "c"
25
+ when 0010000 then "p"
26
+ else "?"
27
+ end
28
+ s += (stat.mode & 0400) == 0400 ? "r" : "-"
29
+ s += (stat.mode & 0200) == 0200 ? "w" : "-"
30
+ s += (stat.mode & 0100) == 0100 ? "x" : "-"
31
+ s += (stat.mode & 0040) == 0040 ? "r" : "-"
32
+ s += (stat.mode & 0020) == 0020 ? "w" : "-"
33
+ s += (stat.mode & 0010) == 0010 ? "x" : "-"
34
+ s += (stat.mode & 0004) == 0004 ? "r" : "-"
35
+ s += (stat.mode & 0002) == 0002 ? "w" : "-"
36
+ s += (stat.mode & 0001) == 0001 ? "x" : "-"
37
+ s
38
+ end
39
+
40
+ def longname_nlink stat
41
+ stat.nlink.to_s.rjust(3, " ")
42
+ end
43
+
44
+ def longname_user stat
45
+ (::Etc.getpwuid(stat.uid).name rescue stat.uid).to_s.ljust(8, " ")
46
+ end
47
+
48
+ def longname_group stat
49
+ (::Etc.getgrgid(stat.gid).name rescue stat.gid).to_s.ljust(8, " ")
50
+ end
51
+
52
+ def longname_size stat
53
+ stat.size.to_s.rjust(8, " ")
54
+ end
55
+
56
+ def longname_mtime stat
57
+ if stat.mtime.year == ::Time.now.year
58
+ stat.mtime.strftime "%b %e %H:%M"
59
+ else
60
+ stat.mtime.strftime "%b %e %Y"
61
+ end
62
+ end
63
+
64
+ def longname dir, entry
65
+ stat = ::File.lstat(::File.join(dir.path, entry))
66
+ [
67
+ longname_permissions(stat),
68
+ longname_nlink(stat),
69
+ longname_user(stat),
70
+ longname_group(stat),
71
+ longname_size(stat),
72
+ longname_mtime(stat),
73
+ entry,
74
+ ].join(" ")
75
+ end
76
+
77
+ def attrs dir, entry
78
+ stat = ::File.lstat(::File.join(dir.path, entry))
79
+ attrs = ::Hash.new
80
+ attrs[:"size"] = stat.size if stat.size
81
+ attrs[:"uid"] = stat.uid if stat.uid
82
+ attrs[:"gid"] = stat.gid if stat.gid
83
+ attrs[:"permissions"] = stat.mode if stat.mode
84
+ attrs[:"atime"] = stat.atime.to_i if stat.atime
85
+ attrs[:"mtime"] = stat.mtime.to_i if stat.mtime
86
+ attrs
87
+ 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
+ end
131
+ end
132
+ end
133
+ end
134
+ end
@@ -0,0 +1,57 @@
1
+ module HrrRbSftp
2
+ class Protocol
3
+ class Version1
4
+ module Packet
5
+ class SSH_FXP_REMOVE
6
+ include Common::Packetable
7
+
8
+ TYPE = 13
9
+
10
+ FORMAT = [
11
+ [DataType::Byte, :"type" ],
12
+ [DataType::Uint32, :"request-id"],
13
+ [DataType::String, :"filename" ],
14
+ ]
15
+
16
+ def respond_to request
17
+ begin
18
+ File.delete(request[:"filename"])
19
+ {
20
+ :"type" => SSH_FXP_STATUS::TYPE,
21
+ :"request-id" => request[:"request-id"],
22
+ :"code" => SSH_FXP_STATUS::SSH_FX_OK,
23
+ :"error message" => "Success",
24
+ :"language tag" => "",
25
+ }
26
+ rescue Errno::ENOENT
27
+ {
28
+ :"type" => SSH_FXP_STATUS::TYPE,
29
+ :"request-id" => request[:"request-id"],
30
+ :"code" => SSH_FXP_STATUS::SSH_FX_NO_SUCH_FILE,
31
+ :"error message" => "No such file or directory",
32
+ :"language tag" => "",
33
+ }
34
+ rescue Errno::EACCES
35
+ {
36
+ :"type" => SSH_FXP_STATUS::TYPE,
37
+ :"request-id" => request[:"request-id"],
38
+ :"code" => SSH_FXP_STATUS::SSH_FX_PERMISSION_DENIED,
39
+ :"error message" => "Permission denied",
40
+ :"language tag" => "",
41
+ }
42
+ rescue => e
43
+ log_error { [e.backtrace[0], ": ", e.message, " (", e.class.to_s, ")\n\t", e.backtrace[1..-1].join("\n\t")].join }
44
+ {
45
+ :"type" => SSH_FXP_STATUS::TYPE,
46
+ :"request-id" => request[:"request-id"],
47
+ :"code" => SSH_FXP_STATUS::SSH_FX_FAILURE,
48
+ :"error message" => e.message,
49
+ :"language tag" => "",
50
+ }
51
+ end
52
+ end
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,57 @@
1
+ module HrrRbSftp
2
+ class Protocol
3
+ class Version1
4
+ module Packet
5
+ class SSH_FXP_MKDIR
6
+ include Common::Packetable
7
+
8
+ TYPE = 14
9
+
10
+ FORMAT = [
11
+ [DataType::Byte, :"type" ],
12
+ [DataType::Uint32, :"request-id"],
13
+ [DataType::String, :"path" ],
14
+ ]
15
+
16
+ def respond_to request
17
+ begin
18
+ Dir.mkdir request[:"path"]
19
+ {
20
+ :"type" => SSH_FXP_STATUS::TYPE,
21
+ :"request-id" => request[:"request-id"],
22
+ :"code" => SSH_FXP_STATUS::SSH_FX_OK,
23
+ :"error message" => "Success",
24
+ :"language tag" => "",
25
+ }
26
+ rescue Errno::EACCES
27
+ {
28
+ :"type" => SSH_FXP_STATUS::TYPE,
29
+ :"request-id" => request[:"request-id"],
30
+ :"code" => SSH_FXP_STATUS::SSH_FX_PERMISSION_DENIED,
31
+ :"error message" => "Permission denied",
32
+ :"language tag" => "",
33
+ }
34
+ rescue Errno::EEXIST
35
+ {
36
+ :"type" => SSH_FXP_STATUS::TYPE,
37
+ :"request-id" => request[:"request-id"],
38
+ :"code" => SSH_FXP_STATUS::SSH_FX_FAILURE,
39
+ :"error message" => "File exists",
40
+ :"language tag" => "",
41
+ }
42
+ rescue => e
43
+ log_error { [e.backtrace[0], ": ", e.message, " (", e.class.to_s, ")\n\t", e.backtrace[1..-1].join("\n\t")].join }
44
+ {
45
+ :"type" => SSH_FXP_STATUS::TYPE,
46
+ :"request-id" => request[:"request-id"],
47
+ :"code" => SSH_FXP_STATUS::SSH_FX_FAILURE,
48
+ :"error message" => e.message,
49
+ :"language tag" => "",
50
+ }
51
+ end
52
+ end
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,73 @@
1
+ module HrrRbSftp
2
+ class Protocol
3
+ class Version1
4
+ module Packet
5
+ class SSH_FXP_RMDIR
6
+ include Common::Packetable
7
+
8
+ TYPE = 15
9
+
10
+ FORMAT = [
11
+ [DataType::Byte, :"type" ],
12
+ [DataType::Uint32, :"request-id"],
13
+ [DataType::String, :"path" ],
14
+ ]
15
+
16
+ def respond_to request
17
+ begin
18
+ Dir.rmdir request[:"path"]
19
+ {
20
+ :"type" => SSH_FXP_STATUS::TYPE,
21
+ :"request-id" => request[:"request-id"],
22
+ :"code" => SSH_FXP_STATUS::SSH_FX_OK,
23
+ :"error message" => "Success",
24
+ :"language tag" => "",
25
+ }
26
+ rescue Errno::ENOENT
27
+ {
28
+ :"type" => SSH_FXP_STATUS::TYPE,
29
+ :"request-id" => request[:"request-id"],
30
+ :"code" => SSH_FXP_STATUS::SSH_FX_NO_SUCH_FILE,
31
+ :"error message" => "No such file or directory",
32
+ :"language tag" => "",
33
+ }
34
+ rescue Errno::EACCES
35
+ {
36
+ :"type" => SSH_FXP_STATUS::TYPE,
37
+ :"request-id" => request[:"request-id"],
38
+ :"code" => SSH_FXP_STATUS::SSH_FX_PERMISSION_DENIED,
39
+ :"error message" => "Permission denied",
40
+ :"language tag" => "",
41
+ }
42
+ rescue Errno::ENOTDIR
43
+ {
44
+ :"type" => SSH_FXP_STATUS::TYPE,
45
+ :"request-id" => request[:"request-id"],
46
+ :"code" => SSH_FXP_STATUS::SSH_FX_FAILURE,
47
+ :"error message" => "Not a directory",
48
+ :"language tag" => "",
49
+ }
50
+ rescue Errno::ENOTEMPTY
51
+ {
52
+ :"type" => SSH_FXP_STATUS::TYPE,
53
+ :"request-id" => request[:"request-id"],
54
+ :"code" => SSH_FXP_STATUS::SSH_FX_FAILURE,
55
+ :"error message" => "Directory not empty",
56
+ :"language tag" => "",
57
+ }
58
+ rescue => e
59
+ log_error { [e.backtrace[0], ": ", e.message, " (", e.class.to_s, ")\n\t", e.backtrace[1..-1].join("\n\t")].join }
60
+ {
61
+ :"type" => SSH_FXP_STATUS::TYPE,
62
+ :"request-id" => request[:"request-id"],
63
+ :"code" => SSH_FXP_STATUS::SSH_FX_FAILURE,
64
+ :"error message" => e.message,
65
+ :"language tag" => "",
66
+ }
67
+ end
68
+ end
69
+ end
70
+ end
71
+ end
72
+ end
73
+ end