ffi-libarchive 0.2.0 → 0.4.1
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.
- checksums.yaml +5 -5
- data/Gemfile +3 -3
- data/LICENSE +201 -674
- data/README.md +69 -4
- data/Rakefile +26 -9
- data/VERSION +1 -0
- data/ffi-libarchive.gemspec +13 -13
- data/lib/ffi-libarchive.rb +10 -11
- data/lib/ffi-libarchive/archive.rb +94 -43
- data/lib/ffi-libarchive/entry.rb +148 -156
- data/lib/ffi-libarchive/reader.rb +31 -34
- data/lib/ffi-libarchive/stat.rb +14 -14
- data/lib/ffi-libarchive/version.rb +1 -1
- data/lib/ffi-libarchive/writer.rb +27 -34
- data/test/sets/ts_read.rb +91 -93
- data/test/sets/ts_write.rb +93 -93
- data/test/test_ffi-libarchive.rb +4 -4
- metadata +22 -18
- data/.gitattributes +0 -6
- data/.gitignore +0 -55
- data/.rubocop.yml +0 -41
- data/.yardopts +0 -5
data/lib/ffi-libarchive/entry.rb
CHANGED
@@ -1,7 +1,5 @@
|
|
1
1
|
module Archive
|
2
|
-
|
3
2
|
class Entry
|
4
|
-
|
5
3
|
S_IFMT = 0170000
|
6
4
|
S_IFSOCK = 0140000 # socket
|
7
5
|
S_IFLNK = 0120000 # symbolic link
|
@@ -19,44 +17,42 @@ module Archive
|
|
19
17
|
CHARACTER_SPECIAL = 0020000 # character device
|
20
18
|
FIFO = 0010000 # FIFO
|
21
19
|
|
22
|
-
def self.from_pointer
|
20
|
+
def self.from_pointer(entry)
|
23
21
|
new entry
|
24
22
|
end
|
25
23
|
|
26
|
-
def initialize
|
24
|
+
def initialize(entry = nil)
|
27
25
|
@entry_free = [true]
|
28
26
|
if entry
|
29
27
|
@entry = entry
|
30
28
|
yield self if block_given?
|
31
29
|
else
|
32
|
-
@entry = C
|
30
|
+
@entry = C.archive_entry_new
|
33
31
|
raise Error, @entry unless @entry
|
34
32
|
|
35
33
|
if block_given?
|
36
34
|
result = yield self
|
37
|
-
C
|
35
|
+
C.archive_entry_free(@entry)
|
38
36
|
@entry = nil
|
39
37
|
return result
|
40
38
|
else
|
41
39
|
@entry_free[0] = false
|
42
|
-
ObjectSpace.define_finalizer(
|
40
|
+
ObjectSpace.define_finalizer(self, Entry.finalizer(@entry, @entry_free))
|
43
41
|
end
|
44
42
|
end
|
45
43
|
end
|
46
44
|
|
47
|
-
def self.finalizer
|
48
|
-
|
49
|
-
unless entry_free[0]
|
50
|
-
C::archive_entry_free(entry)
|
51
|
-
end
|
45
|
+
def self.finalizer(entry, entry_free)
|
46
|
+
proc do |*_args|
|
47
|
+
C.archive_entry_free(entry) unless entry_free[0]
|
52
48
|
end
|
53
49
|
end
|
54
50
|
|
55
51
|
def close
|
56
52
|
# TODO: do we need synchronization here?
|
57
|
-
if @entry
|
53
|
+
if @entry && !@entry_free[0]
|
58
54
|
@entry_free[0] = true
|
59
|
-
C
|
55
|
+
C.archive_entry_free(@entry)
|
60
56
|
end
|
61
57
|
ensure
|
62
58
|
@entry = nil
|
@@ -68,415 +64,411 @@ module Archive
|
|
68
64
|
end
|
69
65
|
|
70
66
|
def atime
|
71
|
-
Time.at C
|
67
|
+
Time.at C.archive_entry_atime(entry)
|
72
68
|
end
|
73
69
|
|
74
|
-
def atime=
|
70
|
+
def atime=(time)
|
75
71
|
set_atime time, 0
|
76
72
|
end
|
77
73
|
|
78
|
-
def set_atime
|
79
|
-
C
|
74
|
+
def set_atime(time, nsec)
|
75
|
+
C.archive_entry_set_atime(entry, time.to_i, nsec)
|
80
76
|
end
|
81
77
|
|
82
78
|
def atime_is_set?
|
83
|
-
C
|
79
|
+
C.archive_entry_atime_is_set(entry) != 0
|
84
80
|
end
|
85
81
|
|
86
82
|
def atime_nsec
|
87
|
-
C
|
83
|
+
C.archive_entry_atime_nsec(entry)
|
88
84
|
end
|
89
85
|
|
90
86
|
def birthtime
|
91
|
-
Time.at C
|
87
|
+
Time.at C.archive_entry_birthtime(entry)
|
92
88
|
end
|
93
89
|
|
94
|
-
def birthtime=
|
90
|
+
def birthtime=(time)
|
95
91
|
set_birthtime time, 0
|
96
92
|
end
|
97
93
|
|
98
|
-
def set_birthtime
|
99
|
-
C
|
94
|
+
def set_birthtime(time, nsec)
|
95
|
+
C.archive_entry_set_birthtime(entry, time.to_i, nsec)
|
100
96
|
end
|
101
97
|
|
102
98
|
def birthtime_is_set?
|
103
|
-
C
|
99
|
+
C.archive_entry_birthtime_is_set(entry) != 0
|
104
100
|
end
|
105
101
|
|
106
102
|
def birthtime_nsec
|
107
|
-
C
|
103
|
+
C.archive_entry_birthtime_nsec(entry)
|
108
104
|
end
|
109
105
|
|
110
106
|
def ctime
|
111
|
-
Time.at C
|
107
|
+
Time.at C.archive_entry_ctime(entry)
|
112
108
|
end
|
113
109
|
|
114
|
-
def ctime=
|
110
|
+
def ctime=(time)
|
115
111
|
set_ctime time, 0
|
116
112
|
end
|
117
113
|
|
118
|
-
def set_ctime
|
119
|
-
C
|
114
|
+
def set_ctime(time, nsec)
|
115
|
+
C.archive_entry_set_ctime(entry, time.to_i, nsec)
|
120
116
|
end
|
121
117
|
|
122
118
|
def ctime_is_set?
|
123
|
-
C
|
119
|
+
C.archive_entry_ctime_is_set(entry) != 0
|
124
120
|
end
|
125
121
|
|
126
122
|
def ctime_nsec
|
127
|
-
C
|
123
|
+
C.archive_entry_ctime_nsec(entry)
|
128
124
|
end
|
129
125
|
|
130
126
|
def block_special?
|
131
|
-
C
|
127
|
+
C.archive_entry_filetype(entry) & S_IFMT == S_IFBLK
|
132
128
|
end
|
133
129
|
|
134
130
|
def character_special?
|
135
|
-
C
|
131
|
+
C.archive_entry_filetype(entry) & S_IFMT == S_IFCHR
|
136
132
|
end
|
137
133
|
|
138
134
|
def directory?
|
139
|
-
C
|
135
|
+
C.archive_entry_filetype(entry) & S_IFMT == S_IFDIR
|
140
136
|
end
|
141
137
|
|
142
138
|
def fifo?
|
143
|
-
C
|
139
|
+
C.archive_entry_filetype(entry) & S_IFMT == S_IFIFO
|
144
140
|
end
|
145
141
|
|
146
142
|
def regular?
|
147
|
-
C
|
143
|
+
C.archive_entry_filetype(entry) & S_IFMT == S_IFREG
|
148
144
|
end
|
149
|
-
alias
|
145
|
+
alias file? regular?
|
150
146
|
|
151
147
|
def socket?
|
152
|
-
C
|
148
|
+
C.archive_entry_filetype(entry) & S_IFMT == S_IFSOCK
|
153
149
|
end
|
154
150
|
|
155
151
|
def symbolic_link?
|
156
|
-
C
|
152
|
+
C.archive_entry_filetype(entry) & S_IFMT == S_IFLNK
|
157
153
|
end
|
158
154
|
|
159
|
-
def copy_fflags_text
|
160
|
-
C
|
155
|
+
def copy_fflags_text(fflags_text)
|
156
|
+
C.archive_entry_copy_fflags_text(entry, fflags_text)
|
161
157
|
nil
|
162
158
|
end
|
163
159
|
|
164
|
-
def copy_gname
|
165
|
-
C
|
160
|
+
def copy_gname(gname)
|
161
|
+
C.archive_entry_copy_gname(entry, gname)
|
166
162
|
nil
|
167
163
|
end
|
168
164
|
|
169
|
-
def copy_hardlink
|
170
|
-
C
|
165
|
+
def copy_hardlink(lnk)
|
166
|
+
C.archive_entry_copy_hardlink(entry, lnk)
|
171
167
|
nil
|
172
168
|
end
|
173
169
|
|
174
|
-
def copy_link
|
175
|
-
C
|
170
|
+
def copy_link(lnk)
|
171
|
+
C.archive_entry_copy_link(entry, lnk)
|
176
172
|
nil
|
177
173
|
end
|
178
174
|
|
179
|
-
def copy_lstat
|
180
|
-
# TODO get this work without ffi-inliner
|
175
|
+
def copy_lstat(filename)
|
176
|
+
# TODO: get this work without ffi-inliner
|
181
177
|
begin
|
182
178
|
require File.join(Archive::LIBPATH, "ffi-libarchive", "stat")
|
183
179
|
rescue => e
|
184
180
|
raise "ffi-inliner build for copy_stat failed:\n#{e}"
|
185
181
|
end
|
186
182
|
|
187
|
-
stat = Archive::Stat
|
188
|
-
raise Error, "Copy stat failed: #{Archive::Stat
|
189
|
-
|
183
|
+
stat = Archive::Stat.ffi_libarchive_create_lstat(filename)
|
184
|
+
raise Error, "Copy stat failed: #{Archive::Stat.ffi_error}" if stat.null?
|
185
|
+
C.archive_entry_copy_stat(entry, stat)
|
190
186
|
ensure
|
191
|
-
Archive::Stat
|
187
|
+
Archive::Stat.ffi_libarchive_free_stat(stat)
|
192
188
|
end
|
193
189
|
|
194
|
-
def copy_pathname
|
195
|
-
C
|
190
|
+
def copy_pathname(file_name)
|
191
|
+
C.archive_entry_copy_pathname(entry, file_name)
|
196
192
|
nil
|
197
193
|
end
|
198
194
|
|
199
|
-
def copy_sourcepath
|
200
|
-
C
|
195
|
+
def copy_sourcepath(path)
|
196
|
+
C.archive_copy_sourcepath(entry, path)
|
201
197
|
nil
|
202
198
|
end
|
203
199
|
|
204
|
-
def copy_stat
|
205
|
-
# TODO get this work without ffi-inliner
|
200
|
+
def copy_stat(filename)
|
201
|
+
# TODO: get this work without ffi-inliner
|
206
202
|
begin
|
207
203
|
require File.join(Archive::LIBPATH, "ffi-libarchive", "stat")
|
208
204
|
rescue => e
|
209
205
|
raise "ffi-inliner build for copy_stat failed:\n#{e}"
|
210
206
|
end
|
211
207
|
|
212
|
-
stat = Archive::Stat
|
213
|
-
raise Error, "Copy stat failed: #{Archive::Stat
|
214
|
-
|
208
|
+
stat = Archive::Stat.ffi_libarchive_create_stat(filename)
|
209
|
+
raise Error, "Copy stat failed: #{Archive::Stat.ffi_error}" if stat.null?
|
210
|
+
C.archive_entry_copy_stat(entry, stat)
|
215
211
|
ensure
|
216
|
-
Archive::Stat
|
212
|
+
Archive::Stat.ffi_libarchive_free_stat(stat)
|
217
213
|
end
|
218
214
|
|
219
|
-
def copy_symlink
|
220
|
-
C
|
215
|
+
def copy_symlink(slnk)
|
216
|
+
C.archive_copy_symlink(entry, slnk)
|
221
217
|
nil
|
222
218
|
end
|
223
219
|
|
224
|
-
def copy_uname
|
225
|
-
C
|
220
|
+
def copy_uname(uname)
|
221
|
+
C.archive_copy_uname(entry, uname)
|
226
222
|
nil
|
227
223
|
end
|
228
224
|
|
229
225
|
def dev
|
230
|
-
C
|
226
|
+
C.archive_entry_dev(entry)
|
231
227
|
end
|
232
228
|
|
233
|
-
def dev=
|
234
|
-
C
|
229
|
+
def dev=(dev)
|
230
|
+
C.archive_entry_set_dev(entry, dev)
|
235
231
|
end
|
236
232
|
|
237
233
|
def devmajor
|
238
|
-
C
|
234
|
+
C.archive_entry_devmajor(entry)
|
239
235
|
end
|
240
236
|
|
241
|
-
def devmajor=
|
242
|
-
C
|
237
|
+
def devmajor=(dev)
|
238
|
+
C.archive_entry_set_devmajor(entry, dev)
|
243
239
|
end
|
244
240
|
|
245
241
|
def devminor
|
246
|
-
C
|
242
|
+
C.archive_entry_devminor(entry)
|
247
243
|
end
|
248
244
|
|
249
|
-
def devminor=
|
250
|
-
C
|
245
|
+
def devminor=(dev)
|
246
|
+
C.archive_entry_set_devminor(entry, dev)
|
251
247
|
end
|
252
248
|
|
253
249
|
def fflags
|
254
250
|
set = FFI::MemoryPointer.new :long
|
255
251
|
clear = FFI::MemoryPointer.new :long
|
256
|
-
C
|
252
|
+
C.archive_entry_fflags(entry, set, clear)
|
257
253
|
[set.get_long(0), clear.get_long(0)]
|
258
254
|
end
|
259
255
|
|
260
256
|
def fflags_text
|
261
|
-
C
|
257
|
+
C.archive_entry_fflags_text(entry)
|
262
258
|
end
|
263
259
|
|
264
260
|
def filetype
|
265
|
-
C
|
261
|
+
C.archive_entry_filetype(entry)
|
266
262
|
end
|
267
263
|
|
268
|
-
def filetype=
|
269
|
-
if type.
|
270
|
-
|
271
|
-
end
|
272
|
-
C::archive_entry_set_filetype(entry, type)
|
264
|
+
def filetype=(type)
|
265
|
+
type = Entry.const_get type.to_s.upcase.to_sym if type.is_a? Symbol
|
266
|
+
C.archive_entry_set_filetype(entry, type)
|
273
267
|
end
|
274
268
|
|
275
269
|
def gid
|
276
|
-
C
|
270
|
+
C.archive_entry_gid(entry)
|
277
271
|
end
|
278
272
|
|
279
|
-
def gid=
|
280
|
-
C
|
273
|
+
def gid=(gid)
|
274
|
+
C.archive_entry_set_gid(entry, gid)
|
281
275
|
end
|
282
276
|
|
283
277
|
def gname
|
284
|
-
C
|
278
|
+
C.archive_entry_gname(entry)
|
285
279
|
end
|
286
280
|
|
287
|
-
def gname=
|
288
|
-
C
|
281
|
+
def gname=(gname)
|
282
|
+
C.archive_entry_set_gname(entry, gname)
|
289
283
|
end
|
290
284
|
|
291
285
|
def hardlink
|
292
|
-
C
|
286
|
+
C.archive_entry_hardlink(entry)
|
293
287
|
end
|
294
288
|
|
295
|
-
def hardlink=
|
296
|
-
C
|
289
|
+
def hardlink=(lnk)
|
290
|
+
C.archive_entry_set_hardlink(entry, lnk)
|
297
291
|
end
|
298
292
|
|
299
293
|
def ino
|
300
|
-
C
|
294
|
+
C.archive_entry_ino(entry)
|
301
295
|
end
|
302
296
|
|
303
|
-
def ino=
|
304
|
-
C
|
297
|
+
def ino=(ino)
|
298
|
+
C.archive_entry_set_ino(entry, ino)
|
305
299
|
end
|
306
300
|
|
307
|
-
def link=
|
308
|
-
C
|
301
|
+
def link=(lnk)
|
302
|
+
C.archive_entry_set_link(entry, lnk)
|
309
303
|
end
|
310
304
|
|
311
305
|
def mode
|
312
|
-
C
|
306
|
+
C.archive_entry_mode(entry)
|
313
307
|
end
|
314
308
|
|
315
|
-
def mode=
|
316
|
-
C
|
309
|
+
def mode=(mode)
|
310
|
+
C.archive_entry_set_mode(entry, mode)
|
317
311
|
end
|
318
312
|
|
319
313
|
def mtime
|
320
|
-
Time.at C
|
314
|
+
Time.at C.archive_entry_mtime(entry)
|
321
315
|
end
|
322
316
|
|
323
|
-
def mtime=
|
317
|
+
def mtime=(time)
|
324
318
|
set_mtime time, 0
|
325
319
|
end
|
326
320
|
|
327
|
-
def set_mtime
|
328
|
-
C
|
321
|
+
def set_mtime(time, nsec)
|
322
|
+
C.archive_entry_set_mtime(entry, time.to_i, nsec)
|
329
323
|
end
|
330
324
|
|
331
325
|
def mtime_is_set?
|
332
|
-
C
|
326
|
+
C.archive_entry_mtime_is_set(entry) != 0
|
333
327
|
end
|
334
328
|
|
335
329
|
def mtime_nsec
|
336
|
-
C
|
330
|
+
C.archive_entry_mtime_nsec(entry)
|
337
331
|
end
|
338
332
|
|
339
333
|
def nlink
|
340
|
-
C
|
334
|
+
C.archive_entry_nlink(entry)
|
341
335
|
end
|
342
336
|
|
343
|
-
def nlink=
|
344
|
-
C
|
337
|
+
def nlink=(nlink)
|
338
|
+
C.archive_entry_set_nlink(entry, nlink)
|
345
339
|
end
|
346
340
|
|
347
341
|
def pathname
|
348
|
-
C
|
342
|
+
C.archive_entry_pathname(entry)
|
349
343
|
end
|
350
344
|
|
351
|
-
def pathname=
|
352
|
-
C
|
345
|
+
def pathname=(path)
|
346
|
+
C.archive_entry_set_pathname(entry, path)
|
353
347
|
end
|
354
348
|
|
355
|
-
def perm=
|
356
|
-
C
|
349
|
+
def perm=(perm)
|
350
|
+
C.archive_entry_set_perm(entry, perm)
|
357
351
|
end
|
358
352
|
|
359
353
|
def rdev
|
360
|
-
C
|
354
|
+
C.archive_entry_rdev(entry)
|
361
355
|
end
|
362
356
|
|
363
|
-
def rdev=
|
364
|
-
C
|
357
|
+
def rdev=(dev)
|
358
|
+
C.archive_entry_set_rdev(entry, dev)
|
365
359
|
end
|
366
360
|
|
367
361
|
def rdevmajor
|
368
|
-
C
|
362
|
+
C.archive_entry_rdevmajor(entry)
|
369
363
|
end
|
370
364
|
|
371
|
-
def rdevmajor=
|
372
|
-
C
|
365
|
+
def rdevmajor=(dev)
|
366
|
+
C.archive_entry_set_rdevmajor(entry, dev)
|
373
367
|
end
|
374
368
|
|
375
369
|
def rdevminor
|
376
|
-
C
|
370
|
+
C.archive_entry_rdevminor(entry)
|
377
371
|
end
|
378
372
|
|
379
|
-
def rdevminor=
|
380
|
-
C
|
373
|
+
def rdevminor=(dev)
|
374
|
+
C.archive_entry_set_rdevminor(entry, dev)
|
381
375
|
end
|
382
376
|
|
383
|
-
def set_fflags
|
384
|
-
C
|
377
|
+
def set_fflags(set, clear)
|
378
|
+
C.archive_entry_set_fflags(entry, set, clear)
|
385
379
|
end
|
386
380
|
|
387
381
|
def size
|
388
|
-
C
|
382
|
+
C.archive_entry_size(entry)
|
389
383
|
end
|
390
384
|
|
391
|
-
def size=
|
392
|
-
C
|
385
|
+
def size=(size)
|
386
|
+
C.archive_entry_set_size(entry, size)
|
393
387
|
end
|
394
388
|
|
395
389
|
def size_is_set?
|
396
|
-
C
|
390
|
+
C.archive_entry_size_is_set(entry) != 0
|
397
391
|
end
|
398
392
|
|
399
393
|
def sourcepath
|
400
|
-
C
|
394
|
+
C.archive_entry_sourcepath(entry)
|
401
395
|
end
|
402
396
|
|
403
397
|
def strmode
|
404
|
-
C
|
398
|
+
C.archive_entry_strmode(entry)
|
405
399
|
end
|
406
400
|
|
407
401
|
def symlink
|
408
|
-
C
|
402
|
+
C.archive_entry_symlink(entry)
|
409
403
|
end
|
410
404
|
|
411
|
-
def symlink=
|
412
|
-
C
|
405
|
+
def symlink=(slnk)
|
406
|
+
C.archive_entry_set_symlink(entry, slnk)
|
413
407
|
end
|
414
408
|
|
415
409
|
def uid
|
416
|
-
C
|
410
|
+
C.archive_entry_uid(entry)
|
417
411
|
end
|
418
412
|
|
419
|
-
def uid=
|
420
|
-
C
|
413
|
+
def uid=(uid)
|
414
|
+
C.archive_entry_set_uid(entry, uid)
|
421
415
|
end
|
422
416
|
|
423
417
|
def uname
|
424
|
-
C
|
418
|
+
C.archive_entry_uname(entry)
|
425
419
|
end
|
426
420
|
|
427
|
-
def uname=
|
428
|
-
C
|
421
|
+
def uname=(uname)
|
422
|
+
C.archive_entry_set_uname(entry, uname)
|
429
423
|
end
|
430
424
|
|
431
425
|
def unset_atime
|
432
|
-
C
|
426
|
+
C.archive_entry_unset_atime(entry)
|
433
427
|
end
|
434
428
|
|
435
429
|
def unset_birthtime
|
436
|
-
C
|
430
|
+
C.archive_entry_unset_birthtime(entry)
|
437
431
|
end
|
438
432
|
|
439
433
|
def unset_ctime
|
440
|
-
C
|
434
|
+
C.archive_entry_unset_ctime(entry)
|
441
435
|
end
|
442
436
|
|
443
437
|
def unset_mtime
|
444
|
-
C
|
438
|
+
C.archive_entry_unset_mtime(entry)
|
445
439
|
end
|
446
440
|
|
447
441
|
def unset_size
|
448
|
-
C
|
442
|
+
C.archive_entry_unset_size(entry)
|
449
443
|
end
|
450
444
|
|
451
|
-
def xattr_add_entry
|
452
|
-
C
|
445
|
+
def xattr_add_entry(name, value)
|
446
|
+
C.archive_entry_xattr_add_entry(entry, name, value, value.size)
|
453
447
|
end
|
454
448
|
|
455
449
|
def xattr_clear
|
456
|
-
C
|
450
|
+
C.archive_entry_xattr_clear(entry)
|
457
451
|
end
|
458
452
|
|
459
453
|
def xattr_count
|
460
|
-
C
|
454
|
+
C.archive_entry_xattr_count(entry)
|
461
455
|
end
|
462
456
|
|
463
457
|
def xattr_next
|
464
458
|
name = FFI::MemoryPointer.new :pointer
|
465
459
|
value = FFI::MemoryPointer.new :pointer
|
466
460
|
size = FFI::MemoryPointer.new :size_t
|
467
|
-
if C
|
461
|
+
if C.archive_entry_xattr_next(entry, name, value, size) != C::OK
|
468
462
|
return nil
|
469
463
|
else
|
470
464
|
# TODO: someday size.read_size_t could work
|
471
465
|
return [name.null? ? nil : name.read_string,
|
472
|
-
value.null? ? nil : value.get_string(0,size.read_ulong)]
|
466
|
+
value.null? ? nil : value.get_string(0, size.read_ulong)]
|
473
467
|
end
|
474
468
|
end
|
475
469
|
|
476
470
|
def xattr_reset
|
477
|
-
C
|
471
|
+
C.archive_entry_xattr_reset(entry)
|
478
472
|
end
|
479
|
-
|
480
473
|
end
|
481
|
-
|
482
474
|
end
|