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.
- data/CHANGES +6 -0
- data/MANIFEST +5 -2
- data/README +9 -4
- data/Rakefile +3 -25
- data/lib/solaris/file.rb +370 -0
- data/lib/solaris/file/constants.rb +31 -0
- data/lib/solaris/file/functions.rb +19 -0
- data/lib/solaris/file/stat.rb +16 -0
- data/lib/solaris/file/structs.rb +11 -0
- data/solaris-file.gemspec +17 -20
- data/test/test_solaris_file.rb +115 -49
- metadata +58 -70
- data/ext/extconf.rb +0 -9
- data/ext/solaris/sfile.c +0 -498
- data/ext/solaris/sfile.h +0 -87
@@ -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
|
data/solaris-file.gemspec
CHANGED
@@ -1,34 +1,31 @@
|
|
1
1
|
require 'rubygems'
|
2
2
|
|
3
|
-
Gem::Specification.new do |
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
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
|
-
|
14
|
+
spec.rubyforge_project = 'solarisutils'
|
17
15
|
|
18
|
-
|
16
|
+
spec.extra_rdoc_files = [
|
19
17
|
'README',
|
20
18
|
'CHANGES',
|
21
19
|
'MANIFEST',
|
22
|
-
'ext/solaris/sfile.c'
|
23
20
|
]
|
24
21
|
|
25
|
-
|
26
|
-
|
22
|
+
spec.add_development_dependency('test-unit', '>= 2.5.0')
|
23
|
+
spec.add_development_dependency('sys-filesystem', '>= 0.3.1')
|
27
24
|
|
28
|
-
|
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
|
32
|
-
|
28
|
+
trivial and door files, an interfaces for the resolvepath()
|
29
|
+
function, and an overloaded ftype method.
|
33
30
|
EOF
|
34
31
|
end
|
data/test/test_solaris_file.rb
CHANGED
@@ -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 '
|
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.
|
41
|
+
assert_equal('0.4.0', File::SOLARIS_VERSION)
|
45
42
|
end
|
46
43
|
|
47
44
|
# SINGLETON METHODS
|
48
45
|
|
49
|
-
|
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
|
-
|
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
|
-
|
62
|
-
|
63
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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::
|
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
|
-
|
94
|
-
assert_raise(
|
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
|
-
|
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
|
-
|
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
|
-
|
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(
|
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
|
-
|
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
|
-
|
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(
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
229
|
+
test "ftype singleton method is still defined" do
|
184
230
|
assert_respond_to(File, :ftype)
|
185
231
|
end
|
186
232
|
|
187
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
|