solaris-file 0.3.7 → 0.4.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.
@@ -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