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.
- 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
|
|