solaris-file 0.3.7 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,31 @@
1
+ module Solaris
2
+ module Constants
3
+ GETACL = 1
4
+ SETACL = 2
5
+ GETACLCNT = 3
6
+ MIN_ACL_ENTRIES = 4
7
+
8
+ USER_OBJ = (0x01)
9
+ USER = (0x02)
10
+ GROUP_OBJ = (0x04)
11
+ GROUP = (0x08)
12
+ CLASS_OBJ = (0x10)
13
+ OTHER_OBJ = (0x20)
14
+ ACL_DEFAULT = (0x1000)
15
+ DEF_USER_OBJ = (ACL_DEFAULT | USER_OBJ)
16
+ DEF_USER = (ACL_DEFAULT | USER)
17
+ DEF_GROUP_OBJ = (ACL_DEFAULT | GROUP_OBJ)
18
+ DEF_GROUP = (ACL_DEFAULT | GROUP)
19
+ DEF_CLASS_OBJ = (ACL_DEFAULT | CLASS_OBJ)
20
+ DEF_OTHER_OBJ = (ACL_DEFAULT | OTHER_OBJ)
21
+
22
+ GRP_ERROR = 1
23
+ USER_ERROR = 2
24
+ OTHER_ERROR = 3
25
+ CLASS_ERROR = 4
26
+ DUPLICATE_ERROR = 5
27
+ MISS_ERROR = 6
28
+ MEM_ERROR = 7
29
+ ENTRY_ERROR = 8
30
+ end
31
+ end
@@ -0,0 +1,19 @@
1
+ require 'ffi'
2
+
3
+ module Solaris
4
+ module Functions
5
+ extend FFI::Library
6
+
7
+ ffi_lib FFI::Library::LIBC
8
+
9
+ attach_function :acl, [:string, :int, :int, :pointer], :int
10
+ attach_function :facl, [:int, :int, :int, :pointer], :int
11
+ attach_function :resolvepath_c, :resolvepath, [:string, :pointer, :ulong], :int
12
+
13
+ ffi_lib :sec
14
+
15
+ attach_function :aclcheck, [:pointer, :int, :pointer], :int
16
+ attach_function :aclfromtext, [:string, :pointer], :pointer
17
+ attach_function :acltotext, [:pointer, :int], :string
18
+ end
19
+ end
@@ -0,0 +1,16 @@
1
+ class File::Stat
2
+ alias ftype_orig ftype
3
+ remove_method :ftype
4
+
5
+ def door?
6
+ mode & 0xF000 == 0xd000
7
+ end
8
+
9
+ def ftype
10
+ if mode & 0xF000 == 0xd000
11
+ "door"
12
+ else
13
+ ftype_orig
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,11 @@
1
+ require 'ffi'
2
+
3
+ module Solaris
4
+ module Structs
5
+ class AclEnt < FFI::Struct
6
+ layout(:a_type, :int, :a_id, :int, :a_perm, :int)
7
+ end
8
+
9
+ ACLStruct = Struct.new('ACLStruct', :acl_type, :acl_id, :acl_perm)
10
+ end
11
+ end
data/solaris-file.gemspec CHANGED
@@ -1,34 +1,31 @@
1
1
  require 'rubygems'
2
2
 
3
- Gem::Specification.new do |gem|
4
- gem.name = 'solaris-file'
5
- gem.version = '0.3.7'
6
- gem.author = 'Daniel J. Berger'
7
- gem.license = 'Artistic 2.0'
8
- gem.email = 'djberg96@gmail.com'
9
- gem.homepage = 'http://www.rubyforge.org/projects/solarisutils'
10
- gem.platform = Gem::Platform::RUBY
11
- gem.summary = 'ACL and other methods for the File class on Solaris'
12
- gem.test_file = 'test/test_solaris_file.rb'
13
- gem.extensions = ['ext/extconf.rb']
14
- gem.files = Dir['**/*'].reject{ |f| f.include?('git') }
3
+ Gem::Specification.new do |spec|
4
+ spec.name = 'solaris-file'
5
+ spec.version = '0.4.0'
6
+ spec.author = 'Daniel J. Berger'
7
+ spec.license = 'Artistic 2.0'
8
+ spec.email = 'djberg96@gmail.com'
9
+ spec.homepage = 'http://www.github.com/djberg96/solaris-file'
10
+ spec.summary = 'ACL and other methods for the File class on Solaris'
11
+ spec.test_file = 'test/test_solaris_file.rb'
12
+ spec.files = Dir['**/*'].reject{ |f| f.include?('git') }
15
13
 
16
- gem.rubyforge_project = 'solarisutils'
14
+ spec.rubyforge_project = 'solarisutils'
17
15
 
18
- gem.extra_rdoc_files = [
16
+ spec.extra_rdoc_files = [
19
17
  'README',
20
18
  'CHANGES',
21
19
  'MANIFEST',
22
- 'ext/solaris/sfile.c'
23
20
  ]
24
21
 
25
- gem.add_development_dependency('test-unit', '>= 2.1.1')
26
- gem.add_development_dependency('sys-filesystem', '>= 0.3.1')
22
+ spec.add_development_dependency('test-unit', '>= 2.5.0')
23
+ spec.add_development_dependency('sys-filesystem', '>= 0.3.1')
27
24
 
28
- gem.description = <<-EOF
25
+ spec.description = <<-EOF
29
26
  The solaris-file library provides Solaris-specific access control
30
27
  methods to the File class. It also provides methods for identifying
31
- trivial and door files, interfaces for the realpath() and resolvepath()
32
- functions, and an overloaded ftype method.
28
+ trivial and door files, an interfaces for the resolvepath()
29
+ function, and an overloaded ftype method.
33
30
  EOF
34
31
  end
@@ -5,10 +5,7 @@
5
5
  # via the 'rake test' task. Note that many tests will be skipped unless you're
6
6
  # on a UFS filesystem.
7
7
  ###############################################################################
8
- require 'rubygems'
9
- gem 'test-unit'
10
-
11
- require 'test/unit'
8
+ require 'test-unit'
12
9
  require 'solaris/file'
13
10
  require 'sys/filesystem'
14
11
 
@@ -41,91 +38,133 @@ class TC_Solaris_File < Test::Unit::TestCase
41
38
  end
42
39
 
43
40
  def test_version
44
- assert_equal('0.3.7', File::SOLARIS_VERSION)
41
+ assert_equal('0.4.0', File::SOLARIS_VERSION)
45
42
  end
46
43
 
47
44
  # SINGLETON METHODS
48
45
 
49
- def test_singleton_acl_read_basic
46
+ test "acl_read singleton method basic functionality" do
50
47
  omit_unless(@@ufs, 'skipped on non-ufs filesystem')
51
48
  assert_respond_to(File, :acl_read)
52
49
  assert_nothing_raised{ File.acl_read(@@file1) }
53
50
  end
54
51
 
55
- def test_singleton_acl_read
52
+ test "acl_read singleton method works as expected" do
56
53
  omit_unless(@@ufs, 'skipped on non-ufs filesystem')
57
54
  assert_nil(File.acl_read(@@file1))
58
55
  assert_kind_of(Array, File.acl_read(@@file2))
56
+ assert_kind_of(Struct::ACLStruct, File.acl_read(@@file2).first)
59
57
  end
60
58
 
61
- def test_singleton_acl_read_expected_errors
62
- assert_raise(Errno::ENOENT){ File.acl_read('bogus') }
63
- assert_raise(ArgumentError){ File.acl_read('bogus' * 500) }
59
+ test "acl_read singleton method returns expected struct values" do
60
+ struct = File.acl_read(@@file2).first
61
+ assert_equal('user', struct.acl_type)
62
+ assert_equal(100, struct.acl_id)
63
+ assert_equal(6, struct.acl_perm)
64
+ end
65
+
66
+ test "acl_read singleton method requires a single argument" do
64
67
  assert_raise(ArgumentError){ File.acl_read }
68
+ assert_raise(ArgumentError){ File.acl_read(@@file1, @@file2) }
69
+ end
70
+
71
+ test "acl_read singleton method raises an error if the file is not found" do
72
+ assert_raise(Errno::ENOENT){ File.acl_read('bogus') }
73
+ end
74
+
75
+ test "acl_read singleton method requires a string argument" do
65
76
  assert_raise(TypeError){ File.acl_read(1) }
66
77
  end
67
78
 
68
- def test_singleton_acl_read_text_basic
79
+ test "acl_read_text singleton method basic functionality" do
69
80
  omit_unless(@@ufs, 'skipped on non-ufs filesystem')
70
81
  assert_respond_to(File, :acl_read_text)
71
82
  assert_nothing_raised{ File.acl_read_text(@@file1) }
72
83
  end
73
84
 
74
- def test_singleton_acl_read_text
85
+ test "acl_read_text singleton method returns expected type of value" do
75
86
  omit_unless(@@ufs, 'skipped on non-ufs filesystem')
76
87
  assert_nil(File.acl_read_text(@@file1))
77
- assert_kind_of(String,File.acl_read_text(@@file2))
88
+ assert_kind_of(String, File.acl_read_text(@@file2))
89
+ assert_equal(@@acl_text, File.acl_read_text(@@file2))
78
90
  end
79
91
 
80
- def test_singleton_acl_read_text_expected_errors
81
- assert_raise(Errno::ENOENT){ File.acl_read_text('bogus') }
92
+ test "acl_read_text singleton method requires a single argument only" do
82
93
  assert_raise(ArgumentError){ File.acl_read_text }
94
+ assert_raise(ArgumentError){ File.acl_read_text(@@file1, @@file2) }
95
+ end
96
+
97
+ test "acl_read_text singleton method raises an error if the argument is invalid" do
98
+ assert_raise(Errno::ENOENT){ File.acl_read_text('bogus') }
99
+ end
100
+
101
+ test "acl_read_text singleton method requires a string argument" do
83
102
  assert_raise(TypeError){ File.acl_read_text(1) }
84
103
  end
85
104
 
86
- def test_singleton_acl_write_text
105
+ test "acl_write_text singleton method basic functionality" do
87
106
  omit_unless(@@ufs, 'skipped on non-ufs filesystem')
88
- acl_text = 'user::rw-,group::r--,mask:r--,other:---'
107
+ acl_text = 'user::rw-,group::rw-,mask:r--,other:---'
89
108
  assert_respond_to(File, :acl_write_text)
90
109
  assert_nothing_raised{ File.acl_write_text(@@file1, acl_text) }
110
+ assert_kind_of(String, File.acl_write_text(@@file1, acl_text))
111
+ end
112
+
113
+ test "acl_write_text singleton method works as expected" do
114
+ acl_text = 'user::rw-,group::rw-,mask:r--,other:---'
115
+ assert_equal(acl_text, File.acl_write_text(@@file1, acl_text))
116
+ #assert_equal(acl_text, File.acl_read_text(@@file1))
91
117
  end
92
118
 
93
- def test_singleton_acl_write_text_expected_errors
94
- assert_raise(File::SolarisError){ File.acl_write_text(@@file1, 'bogus') }
119
+ test "acl_write_text singleton method if text is invalid" do
120
+ assert_raise(ArgumentError){ File.acl_write_text(@@file1, 'bogus') }
121
+ assert_raise_message('invalid ACL text'){ File.acl_write_text(@@file1, 'bogus') }
95
122
  end
96
123
 
97
- def test_singleton_acl_trivial_basic
124
+ test "trivial? singleton method basic functionality" do
98
125
  assert_respond_to(File, :trivial?)
99
126
  assert_nothing_raised{ File.trivial?(@@file1) }
100
127
  assert_boolean(File.trivial?(@@file1))
101
128
  end
102
129
 
103
- def test_singleton_acl_trivial
130
+ test "trivial? singleton method returns the expected value" do
104
131
  omit_unless(@@ufs, 'skipped on non-ufs filesystem')
105
132
  assert_true(File.trivial?(@@file1))
106
133
  assert_false(File.trivial?(@@file2))
107
134
  end
108
135
 
109
- def test_singleton_acl_trivial_expected_errors
136
+ test "trivial? singleton method raises an error if the argument is invalid" do
110
137
  assert_raise(Errno::ENOENT){ File.trivial?('bogus') }
111
- assert_raise(ArgumentError){ File.trivial?('bogus' * 500) }
138
+ assert_raise(Errno::ENAMETOOLONG){ File.trivial?('bogus' * 500) }
139
+ end
140
+
141
+ test "trivial? singleton method requires a single string argument" do
112
142
  assert_raise(ArgumentError){ File.trivial? }
113
143
  assert_raise(TypeError){ File.trivial?(1) }
114
144
  end
115
145
 
116
- def test_singleton_acl_count
146
+ test "acl_count singleton method basic functionality" do
117
147
  assert_respond_to(File, :acl_count)
118
148
  assert_nothing_raised{ File.acl_count(@@file1) }
119
149
  assert_kind_of(Fixnum, File.acl_count(@@file1))
120
150
  end
121
151
 
122
- def test_singleton_acl_count_expected_errors
152
+ test "acl_count singleton method returns the expected value" do
153
+ assert_equal(0, File.acl_count(@@file1))
154
+ assert_equal(6, File.acl_count(@@file2))
155
+ end
156
+
157
+ test "acl_count singleton method raises an error if the argument is invalid" do
123
158
  assert_raise(Errno::ENOENT){ File.acl_count('bogus') }
124
- assert_raise(ArgumentError){ File.acl_count('bogus' * 500) }
159
+ assert_raise(Errno::ENAMETOOLONG){ File.acl_count('bogus' * 500) }
160
+ end
161
+
162
+ test "acl_count singleton method requires a single string argument" do
125
163
  assert_raise(ArgumentError){ File.acl_count }
126
164
  assert_raise(TypeError){ File.acl_count(1) }
127
165
  end
128
166
 
167
+ =begin
129
168
  def test_singleton_realpath_basic
130
169
  assert_respond_to(File, :realpath)
131
170
  assert_nothing_raised{ File.realpath(@dir) }
@@ -145,127 +184,154 @@ class TC_Solaris_File < Test::Unit::TestCase
145
184
  assert_raise(ArgumentError){ File.realpath }
146
185
  assert_raise(TypeError){ File.realpath(1) }
147
186
  end
187
+ =end
148
188
 
149
- def test_singleton_resolvepath_basic
189
+ test "resolvepath singleton method basic functionality" do
150
190
  assert_respond_to(File, :resolvepath)
151
191
  assert_nothing_raised{ File.resolvepath(@dir) }
152
192
  assert_kind_of(String, File.resolvepath(@dir))
153
193
  end
154
194
 
155
- def test_singleton_resolvepath
195
+ test "resolvepath singleton method returns the expected value" do
156
196
  assert_equal(@dir, File.resolvepath(@dir))
157
197
  assert_equal("../examples", File.resolvepath("../examples"))
158
198
  end
159
199
 
160
- def test_singleton_resolvepath_expected_errors
200
+ test "resolvepath singleton method raises an error if the argument is invalid" do
161
201
  assert_raise(Errno::ENOENT){ File.resolvepath('bogus') }
202
+ end
203
+
204
+ test "resolvepath requires a single string argument" do
162
205
  assert_raise(ArgumentError){ File.resolvepath }
163
206
  assert_raise(TypeError){ File.resolvepath(1) }
164
207
  end
165
208
 
166
- def test_singleton_is_door_basic
209
+ test "door? singleton method basic functionality" do
167
210
  assert_respond_to(File, :door?)
168
211
  assert_nothing_raised{ File.door?(@door) }
169
212
  assert_boolean(File.door?(@door))
170
213
  end
171
-
172
- def test_singleton_is_door
214
+
215
+ test "door? singleton method returns the expected result" do
173
216
  assert_true(File.door?(@door))
174
217
  assert_false(File.door?(Dir.pwd))
175
218
  end
176
219
 
177
- def test_singleton_is_door_expected_errors
220
+ test "door? singleton method raises an error if the argument is invalid" do
178
221
  assert_raise(Errno::ENOENT){ File.door?('bogus') }
222
+ end
223
+
224
+ test "door? singleton method requires a single string argument" do
179
225
  assert_raise(ArgumentError){ File.door? }
180
226
  assert_raise(TypeError){ File.door?(1) }
181
227
  end
182
228
 
183
- def test_singleton_ftype_basic
229
+ test "ftype singleton method is still defined" do
184
230
  assert_respond_to(File, :ftype)
185
231
  end
186
232
 
187
- def test_singleton_ftype
233
+ test "overridden ftype singleton method returns expected value" do
188
234
  assert_equal('door', File.ftype(@door))
189
235
  assert_equal('directory', File.ftype(Dir.pwd))
190
236
  end
191
237
 
192
- def test_singleton_ftype_expected_errors
238
+ test "ftype singleton method raises an error if the argument is invalid" do
193
239
  assert_raise(Errno::ENOENT){ File.ftype('bogus') }
240
+ end
241
+
242
+ test "ftype singleton method requires a single string argument" do
194
243
  assert_raise(ArgumentError){ File.ftype }
195
244
  assert_raise(TypeError){ File.ftype(1) }
196
245
  end
197
246
 
198
247
  # INSTANCE METHODS
199
248
 
200
- def test_instance_acl_basic
249
+ test "acl_read instance method basic functionality" do
201
250
  omit_unless(@@ufs, 'skipped on non-ufs filesystem')
202
251
  assert_respond_to(@handle1, :acl_read)
203
252
  assert_nothing_raised{ @handle1.acl_read }
204
253
  end
205
254
 
206
- def test_instance_acl
255
+ test "acl_read instance method works as expected" do
207
256
  omit_unless(@@ufs, 'skipped on non-ufs filesystem')
208
257
  assert_nil(@handle1.acl_read)
209
258
  assert_kind_of(Array, @handle2.acl_read)
210
259
  assert_kind_of(Struct::ACLStruct, @handle2.acl_read.first)
211
260
  end
212
261
 
213
- def test_instance_acl_read_text_basic
262
+ test "acl_read instance method does not accept any arguments" do
263
+ assert_raise(ArgumentError){ @handle1.acl_read('test.txt') }
264
+ end
265
+
266
+ test "acl_read_text instance method dbasic functionality" do
214
267
  omit_unless(@@ufs, 'skipped on non-ufs filesystem')
215
268
  assert_respond_to(@handle1, :acl_read_text)
216
269
  assert_nothing_raised{ @handle1.acl_read_text }
217
270
  end
218
271
 
219
- def test_instance_acl_read_text
272
+ test "acl_read_text instance method returns expected value" do
220
273
  omit_unless(@@ufs, 'skipped on non-ufs filesystem')
221
274
  assert_nil(@handle1.acl_read_text)
222
275
  assert_kind_of(String, @handle2.acl_read_text)
223
276
  end
224
277
 
225
- def test_instance_acl_write_text
278
+ test "acl_write_text instance method basic functionality" do
226
279
  omit_unless(@@ufs, 'skipped on non-ufs filesystem')
227
280
  acl_text = 'user::rw-,group::r--,mask:r--,other:---'
228
281
  assert_respond_to(@handle2, :acl_write_text)
229
282
  assert_nothing_raised{ @handle2.acl_write_text(acl_text) }
230
283
  end
231
284
 
232
- def test_instance_acl_write_text_expected_errors
233
- assert_raise(File::SolarisError){ @handle2.acl_write_text('bogus') }
285
+ test "acl_write_text instance method requires a single string argument" do
234
286
  assert_raise(ArgumentError){ @handle2.acl_write_text }
235
287
  assert_raise(TypeError){ @handle2.acl_write_text(1) }
236
288
  end
237
289
 
238
- def test_instance_acl_trivial_basic
290
+ test "acl_write_text instance method requires a valid acl string" do
291
+ assert_raise(ArgumentError){ @handle2.acl_write_text('bogus') }
292
+ end
293
+
294
+ test "trivial? instance method basic functionality" do
239
295
  assert_respond_to(@handle1, :trivial?)
240
296
  assert_nothing_raised{ @handle1.trivial? }
241
297
  assert_boolean(@handle1.trivial?)
242
298
  end
243
299
 
244
- def test_instance_acl_trivial
300
+ test "trivial? instance method returns the expected value" do
245
301
  assert_true(@handle1.trivial?)
246
302
  assert_false(@handle2.trivial?)
247
303
  end
248
304
 
249
- def test_instance_acl_count_basic
305
+ test "acl_count instance method basic functionality" do
250
306
  omit_unless(@@ufs, 'skipped on non-ufs filesystem')
251
307
  assert_respond_to(@handle1, :acl_count)
252
308
  assert_nothing_raised{ @handle1.acl_count }
253
309
  assert_kind_of(Fixnum, @handle1.acl_count)
254
310
  end
255
311
 
256
- def test_instance_acl_count
312
+ test "acl_count instance method returns the expected value" do
257
313
  omit_unless(@@ufs, 'skipped on non-ufs filesystem')
258
314
  assert_equal(0, @handle1.acl_count)
259
315
  assert_equal(6, @handle2.acl_count)
260
316
  end
261
317
 
262
- def test_stat_door
318
+ test "door? instance method basic functionality" do
263
319
  assert_respond_to(@stat, :door?)
320
+ assert_nothing_raised{ @stat.door? }
321
+ assert_boolean(@stat.door?)
322
+ end
323
+
324
+ test "door? instance method returns the expected value" do
264
325
  assert_true(@stat.door?)
265
326
  end
266
327
 
267
- def test_stat_ftype
328
+ test "ftype instance method basic functionality" do
268
329
  assert_respond_to(@stat, :ftype)
330
+ assert_nothing_raised{ @stat.ftype }
331
+ assert_kind_of(String, @stat.ftype)
332
+ end
333
+
334
+ test "ftype instance method returns the expected value" do
269
335
  assert_equal('door', @stat.ftype)
270
336
  end
271
337