public
Description: Pure Ruby implementation of an SFTP (protocols 1-6) client
Homepage: http://rubyforge.org/projects/net-ssh
Clone URL: git://github.com/jamis/net-sftp.git
Search Repo:
more complete support for file-type detection in protocol versions 1-3
jamis (author)
Wed Apr 23 08:21:02 -0700 2008
commit  3407e96653590c61809449a560b0c3ff9e398ef0
tree    ff68028bde7984de323e1858e9466dd2c3205ff9
parent  05734d70f337d40d16ca6647d3068d3de7bf1e22
...
 
 
 
 
 
1
2
3
...
1
2
3
4
5
6
7
8
0
@@ -1,3 +1,8 @@
0
+=== *unreleased*
0
+
0
+* More complete support for file-type detection in protocol versions 1-3 [Jamis Buck]
0
+
0
+
0
 === 2.0 Preview Release 2 (1.99.1) / 10 Apr 2008
0
 
0
 * Custom properties on Upload instances [Jamis Buck]
...
28
29
30
31
 
 
 
 
 
 
 
 
 
 
 
32
33
34
35
36
37
38
39
...
191
192
193
194
195
196
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
197
198
199
 
 
 
 
 
200
201
202
203
204
 
205
206
207
 
 
 
 
 
208
209
210
211
212
 
213
214
215
 
 
 
 
 
216
217
218
...
28
29
30
 
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
...
201
202
203
 
 
 
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
 
 
245
246
247
248
249
250
251
 
 
 
252
253
 
 
254
255
256
257
258
259
260
 
 
 
261
262
 
 
263
264
265
266
267
268
269
270
0
@@ -28,7 +28,17 @@
0
     F_PERMISSIONS = 0x00000004
0
     F_ACMODTIME = 0x00000008
0
     F_EXTENDED = 0x80000000
0
-
0
+
0
+ T_REGULAR = 1
0
+ T_DIRECTORY = 2
0
+ T_SYMLINK = 3
0
+ T_SPECIAL = 4
0
+ T_UNKNOWN = 5
0
+ T_SOCKET = 6
0
+ T_CHAR_DEVICE = 7
0
+ T_BLOCK_DEVICE = 8
0
+ T_FIFO = 9
0
+
0
     class <<self
0
       # Returns the array of attribute meta-data that defines the structure of
0
       # the attributes packet as described by this version of the protocol.
0
0
0
0
0
0
@@ -191,28 +201,70 @@
0
       attributes[:group]
0
     end
0
 
0
- # Returns true if these attributes appear to describe a directory. This
0
- # is done by comparing the permissions, so if the permissions are not
0
- # available, +nil+ is returned.
0
+ # Inspects the permissions bits to determine what type of entity this
0
+ # attributes object represents. If will return one of the T_ constants.
0
+ def type
0
+ if permissions & 0140000 == 0140000 then
0
+ T_SOCKET
0
+ elsif permissions & 0120000 == 0120000 then
0
+ T_SYMLINK
0
+ elsif permissions & 0100000 == 0100000 then
0
+ T_REGULAR
0
+ elsif permissions & 060000 == 060000 then
0
+ T_BLOCK_DEVICE
0
+ elsif permissions & 040000 == 040000 then
0
+ T_DIRECTORY
0
+ elsif permissions & 020000 == 020000 then
0
+ T_CHAR_DEVICE
0
+ elsif permissions & 010000 == 010000 then
0
+ T_FIFO
0
+ else
0
+ T_UNKNOWN
0
+ end
0
+ end
0
+
0
+ # Returns the type as a symbol, rather than an integer, for easier use in
0
+ # Ruby programs.
0
+ def symbolic_type
0
+ case type
0
+ when T_SOCKET then :socket
0
+ when T_SYMLINK then :symlink
0
+ when T_REGULAR then :regular
0
+ when T_BLOCK_DEVICE then :block_device
0
+ when T_DIRECTORY then :directory
0
+ when T_CHAR_DEVICE then :char_device
0
+ when T_FIFO then :fifo
0
+ when T_SPECIAL then :special
0
+ when T_UNKNOWN then :unknown
0
+ else raise NotImplementedError, "unknown file type #{type} (bug?)"
0
+ end
0
+ end
0
+
0
+ # Returns true if these attributes appear to describe a directory.
0
     def directory?
0
- return nil if permissions.nil?
0
- return (permissions & 040000) == 040000
0
+ case type
0
+ when T_DIRECTORY then true
0
+ when T_UNKNOWN then nil
0
+ else false
0
+ end
0
     end
0
 
0
- # Returns true if these attributes appear to describe a symlink. This
0
- # is done by comparing the permissions, so if the permissions are not
0
- # available, +nil+ is returned.
0
+ # Returns true if these attributes appear to describe a symlink.
0
     def symlink?
0
- return nil if permissions.nil?
0
- return (permissions & 020000) == 020000
0
+ case type
0
+ when T_SYMLINK then true
0
+ when T_UNKNOWN then nil
0
+ else false
0
+ end
0
     end
0
 
0
- # Returns true if these attributes appear to describe a regular file. This
0
- # is done by comparing the permissions, so if the permissions are not
0
- # available, +nil+ is returned.
0
+ # Returns true if these attributes appear to describe a regular file.
0
     def file?
0
- return nil if permissions.nil?
0
- return (permissions & 0100000) == 0100000
0
+ case type
0
+ when T_REGULAR then true
0
+ when T_UNKNOWN then nil
0
+ else false
0
+ end
0
     end
0
 
0
     # Convert the object to a string suitable for passing in an SFTP
...
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
...
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
...
38
39
40
 
 
 
 
 
 
 
 
 
 
41
42
43
...
124
125
126
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
127
128
129
0
@@ -38,16 +38,6 @@
0
     F_OWNERGROUP = 0x00000080
0
     F_SUBSECOND_TIMES = 0x00000100
0
     
0
- T_REGULAR = 1
0
- T_DIRECTORY = 2
0
- T_SYMLINK = 3
0
- T_SPECIAL = 4
0
- T_UNKNOWN = 5
0
- T_SOCKET = 6
0
- T_CHAR_DEVICE = 7
0
- T_BLOCK_DEVICE = 8
0
- T_FIFO = 9
0
-
0
     # A simple struct for representing a single entry in an Access Control
0
     # List. (See Net::SFTP::Constants::ACE)
0
     ACL = Struct.new(:type, :flag, :mask, :who)
0
@@ -134,21 +124,6 @@
0
     def initialize(attributes={})
0
       super
0
       attributes[:type] ||= T_REGULAR
0
- end
0
-
0
- # Returns +true+ if #type is T_DIRECTORY.
0
- def directory?
0
- type == T_DIRECTORY
0
- end
0
-
0
- # Returns +true+ if #type is T_SYMLINK.
0
- def symlink?
0
- type == T_SYMLINK
0
- end
0
-
0
- # Returns +true+ if #type is T_REGULAR.
0
- def file?
0
- type == T_REGULAR
0
     end
0
 
0
     private
...
4
5
6
7
 
8
9
10
...
18
19
20
21
 
22
23
24
...
31
32
33
34
 
35
36
37
38
...
42
43
44
45
 
46
47
48
49
50
 
51
52
53
54
55
...
55
56
57
58
 
59
60
61
62
63
64
65
 
66
67
68
69
70
 
 
 
 
 
 
 
 
 
 
 
 
71
72
73
...
76
77
78
 
 
 
 
 
 
79
...
4
5
6
 
7
8
9
10
...
18
19
20
 
21
22
23
24
...
31
32
33
 
34
35
36
37
38
...
42
43
44
 
45
46
47
48
49
 
50
51
52
53
54
55
...
55
56
57
 
58
59
60
61
62
63
64
 
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
...
88
89
90
91
92
93
94
95
96
97
0
@@ -4,7 +4,7 @@
0
 
0
 class Protocol::V01::TestAttributes < Net::SFTP::TestCase
0
   def test_from_buffer_should_correctly_parse_buffer_and_return_attribute_object
0
- attributes = Net::SFTP::Protocol::V01::Attributes.from_buffer(full_buffer)
0
+ attributes = attributes_factory.from_buffer(full_buffer)
0
 
0
     assert_equal 1234567890, attributes.size
0
     assert_equal 100, attributes.uid
0
@@ -18,7 +18,7 @@
0
   def test_from_buffer_should_correctly_parse_buffer_with_attribute_subset_and_return_attribute_object
0
     buffer = Net::SSH::Buffer.from(:long, 0x4, :long, 0755)
0
 
0
- attributes = Net::SFTP::Protocol::V01::Attributes.from_buffer(buffer)
0
+ attributes = attributes_factory.from_buffer(buffer)
0
 
0
     assert_equal 0755, attributes.permissions
0
 
0
@@ -31,7 +31,7 @@
0
   end
0
 
0
   def test_attributes_to_s_should_build_binary_representation
0
- attributes = Net::SFTP::Protocol::V01::Attributes.new(
0
+ attributes = attributes_factory.new(
0
       :size => 1234567890,
0
       :uid => 100, :gid => 200,
0
       :permissions => 0755,
0
0
@@ -42,12 +42,12 @@
0
   end
0
 
0
   def test_attributes_to_s_should_build_binary_representation_when_subset_is_present
0
- attributes = Net::SFTP::Protocol::V01::Attributes.new(:permissions => 0755)
0
+ attributes = attributes_factory.new(:permissions => 0755)
0
     assert_equal Net::SSH::Buffer.from(:long, 0x4, :long, 0755).to_s, attributes.to_s
0
   end
0
 
0
   def test_attributes_to_s_with_owner_and_group_should_translate_to_uid_and_gid
0
- attributes = Net::SFTP::Protocol::V01::Attributes.new(:owner => "jamis", :group => "sftp")
0
+ attributes = attributes_factory.new(:owner => "jamis", :group => "sftp")
0
     attributes.expects(:require).with("etc").times(2)
0
     Etc.expects(:getpwnam).with("jamis").returns(mock('user', :uid => 100))
0
     Etc.expects(:getgrnam).with("sftp").returns(mock('group', :gid => 200))
0
0
0
@@ -55,19 +55,31 @@
0
   end
0
 
0
   def test_owner_should_translate_from_uid
0
- attributes = Net::SFTP::Protocol::V01::Attributes.new(:uid => 100)
0
+ attributes = attributes_factory.new(:uid => 100)
0
     attributes.expects(:require).with("etc")
0
     Etc.expects(:getpwuid).with(100).returns(mock('user', :name => "jamis"))
0
     assert_equal "jamis", attributes.owner
0
   end
0
 
0
   def test_group_should_translate_from_gid
0
- attributes = Net::SFTP::Protocol::V01::Attributes.new(:gid => 200)
0
+ attributes = attributes_factory.new(:gid => 200)
0
     attributes.expects(:require).with("etc")
0
     Etc.expects(:getgrgid).with(200).returns(mock('group', :name => "sftp"))
0
     assert_equal "sftp", attributes.group
0
   end
0
 
0
+ def test_type_should_infer_type_from_permissions
0
+ assert_equal af::T_SOCKET, af.new(:permissions => 0140755).type
0
+ assert_equal af::T_SYMLINK, af.new(:permissions => 0120755).type
0
+ assert_equal af::T_REGULAR, af.new(:permissions => 0100755).type
0
+ assert_equal af::T_BLOCK_DEVICE, af.new(:permissions => 060755).type
0
+ assert_equal af::T_DIRECTORY, af.new(:permissions => 040755).type
0
+ assert_equal af::T_CHAR_DEVICE, af.new(:permissions => 020755).type
0
+ assert_equal af::T_FIFO, af.new(:permissions => 010755).type
0
+ assert_equal af::T_UNKNOWN, af.new(:permissions => 0755).type
0
+ assert_equal af::T_UNKNOWN, af.new.type
0
+ end
0
+
0
   private
0
 
0
     def full_buffer
0
@@ -76,5 +88,11 @@
0
         :long, 0755, :long, 1234567890, :long, 2345678901,
0
         :long, 1, :string, "first", :string, "second")
0
     end
0
+
0
+ def attributes_factory
0
+ Net::SFTP::Protocol::V01::Attributes
0
+ end
0
+
0
+ alias af attributes_factory
0
 end
...
3
4
5
6
 
7
8
9
...
3
4
5
 
6
7
8
9
0
@@ -3,7 +3,7 @@
0
 class Protocol::V01::TestName < Net::SFTP::TestCase
0
   def setup
0
     @directory = Net::SFTP::Protocol::V01::Name.new("test", "drwxr-x-r-x 89 test test 3026 Mar 10 17:45 test", Net::SFTP::Protocol::V01::Attributes.new(:permissions => 040755))
0
- @link = Net::SFTP::Protocol::V01::Name.new("test", "lrwxr-x-r-x 89 test test 3026 Mar 10 17:45 test", Net::SFTP::Protocol::V01::Attributes.new(:permissions => 020755))
0
+ @link = Net::SFTP::Protocol::V01::Name.new("test", "lrwxr-x-r-x 89 test test 3026 Mar 10 17:45 test", Net::SFTP::Protocol::V01::Attributes.new(:permissions => 0120755))
0
     @file = Net::SFTP::Protocol::V01::Name.new("test", "-rwxr-x-r-x 89 test test 3026 Mar 10 17:45 test", Net::SFTP::Protocol::V01::Attributes.new(:permissions => 0100755))
0
   end
0
 

Comments

    No one has commented yet.